Поиск модели Django очень медленный - PullRequest
0 голосов
/ 14 мая 2019

Я получаю очень медленный поиск в моих моделях Django.

У меня есть две таблицы:

class Scan(models.Model):
    scan_name = models.CharField(max_length=32, unique=True, validators=[alphanumeric_plus_validator])

class ScanProcessingInfo(models.Model):
    scan_name = models.CharField(max_length=32)
    processing_name = models.CharField(max_length=64)
    in_progress = models.BooleanField(default=False)

Когда я выполняю следующую операцию, чтобы получить список всех объектов Scan, которые имеют ScanProcessingInfo для определенного имени_процесса:

scans = models.Scan.objects.all()

        scan_set = []

        for scan in scans:
            if self.set_type_definition.test_scan(scan, self.arg1, self.arg2):
                scan_set.append(scan)


(test_scan routes to)

def get_proc_info_been_done(scan, spd_name):
    try:
        proc_info = models.ScanProcessingInfo.objects.get(scan_name = scan.scan_name)
    except models.ScanProcessingInfo.DoesNotExist:
        proc_info = None

    if proc_info == None:
        return False

    return not proc_info.in_progress

запрос занимает около 10 секунд. Всего 300 сканирований и 10 ScanProcessingInfos. Серверная часть базы данных - это база данных RDS MySQL. Я также ожидаю, что кто-то подскажет мне за использование строк для идентификаторов кросс-таблицы, но я сомневаюсь, что причина здесь.

Я уверен, что делаю что-то явно не так, но был бы признателен за указатель, спасибо.

Ответы [ 2 ]

3 голосов
/ 14 мая 2019

Я думаю, что вы спрашиваете, как получить все сканы, для которых существует соответствующий ScanProcessingInfo.

Первое, что нужно сделать, это объявить фактические отношения. Вам не нужно менять свою базу данных (вы должны, но не обязаны); Вы можете использовать существующее базовое поле, но просто скажите Django, чтобы оно воспринималось как внешний ключ.

class ScanProcessingInfo(models.Model):
    scan = models.ForeignKey('Scan', to_field='scan_name', db_field='scan_name', on_delete=models.DO_NOTHING)

Теперь вы можете использовать это отношение, чтобы получить все сканы за один раз:

scan_set = Scan.objects.exclude(scanprocessinginfo=None)

Редактировать

Чтобы получить все подходящие объекты с определенным атрибутом, используйте синтаксис с двойным подчеркиванием:

scan_set = Scan.objects.filter(scanprocessinginfo__processing_name=spd_name)
0 голосов
/ 14 мая 2019

Использование Отношение многие-к-одному .

scan_name = ForeignKey(Scan, related_name='processing_infos',on_delete=models.CASCADE)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...