2016-11-27 7 views
0

Я ищу надежный способ гарантировать, что для данного экземпляра модели django определенное поле записывается только один раз.Убедитесь, что поле модели django написано только один раз? Атоматичность гарантирована без блокировок

Код должен работать как в представлении, так и в задачах с использованием сельдерея или даже rq.

Я имею в виду, используя следующий фрагмент кода:

from django.db import transaction 
from django.utils.timezone import now 

... 

def perform_writeonce(object_pk): 
    with transaction.atomic(): 
     instance = MyModel.objects.get(pk=object_pk) 

     if instance.value is None: 
      instance.value = 'Value written now : {}'.format(now()) 
      instance.save() 

Цель состоит в том, что значение должно быть записано только один раз и только если его значение равно None.

Уверены ли вы в этом фрагменте или есть что-то, что я пропустил?

Я использую несколько экземпляров оружия и работников сельдерея с одним сервером базы данных postgresql.

Я стараюсь избегать блокировок любой ценой, поэтому любое решение с помощью шлюзов приложений не является хорошим.

Спасибо за любую помощь.

+0

Я уверен. потому что транзакция зависит от уровня db, а не от прикладного уровня. – itzMEonTV

ответ

0

Я ищу надежный способ гарантировать, что для любого данного экземпляра модели django определенное поле записывается только один раз.

Ожидаемое поведение похоже на параметр auto_now_add на поля даты.

auto_now_add не гарантирует, что поле написано только один раз. Вы все равно можете писать в это поле, если хотите. Он просто не отображается по умолчанию в формах администратора и т.д.

Вы можете сделать то же самое для других полей, установив Field.editable https://docs.djangoproject.com/en/1.10/ref/models/fields/#editable

Field.editable

Если False, то поле не будет отображаться в администраторе или любом другом ModelForm. Они также пропускаются во время проверки модели. По умолчанию True.

+0

Извините, я не был ясен, я не хочу реплицировать поведение auto_now_add или редактируемого атрибута. Проблема связана с параллелизмом и одновременным доступом к базе данных с использованием транзакций. Спасибо в любом случае –

+0

Тогда вы должны дать ясное объяснение ожидаемого поведения в вашем вопросе. Если вы хотите писать в поле только один раз, это время должно быть, когда экземпляр сначала сохраняется в базе данных. Если параллелизм является проблемой, код модели может оказаться не подходящим местом для ее решения. Почему бы не использовать очередь задач и позволить сельдерейу делать все обновления для этой конкретной модели? –

+0

Вопрос отредактирован. Теперь может быть более ясно. –