Как реализовать тег синхронизации в Django - PullRequest
0 голосов
/ 26 августа 2009

Мы осуществляем синхронизацию между одной главной базой данных и многими ведомыми базами данных по жесткой линии связи (7 КБ). Чтобы минимизировать объем отправляемых данных, мы помечаем каждую запись, которая была успешно отправлена.

Для этого мы создали следующие модели:

class SynchronizationTag(models.Model):
    STATUSES = ((0, "Invalid"), 
                (1, "Pending"),
                (2, "Synchronized"), 
                )
    status = models.IntegerField(choices=STATUSES, default = 1)
    storage = models.ForeignKey("Storage")

    _content_type = models.ForeignKey(ContentType)
    _object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('_content_type', '_object_id')

class Storage(models.Model):
   id = models.AutoField(primary_key=True)

Чтобы выбрать записи, требующие синхронизации, мы написали общий запрос, который отфильтровывал бы записи, помеченные как синхронизированные из набора запросов.

Мы нашли следующее неоптимальное решение:

delta = queryset.extra(
    select={ 
        "status" : ("SELECT status FROM rv3adapter_synchronizationtag "
                    "WHERE `_content_type_id` = %d and `_object_id`= %s.id and `storage_id` = %d" 
                    % (content_type.pk, table, storage.pk)) 
        },
    where=["`status` <> 2 or `status` is NULL")

Запрос выше теперь не работает, поскольку у нас есть несколько моделей, у которых нет первичных ключей с именем id.

Знаете ли вы, как улучшить / исправить вышеуказанный запрос?

Примечание. Запрос должен возвращать объекты django.

1 Ответ

0 голосов
/ 26 августа 2009

Получить имя поля первичного ключа с помощью queryset.model._meta.pk.name.

Вы также можете найти ._meta.db_table полезным.

Конечно, это - с использованием неофициального API, который не гарантированно совместим с будущими версиями django, но если у вас есть несколько юнит-тестов, у вас все будет хорошо.

...