Заставить Джанго совершить - PullRequest
8 голосов
/ 11 августа 2011

Настройка:

  • Python-скрипт A вставляет данные в базу данных каждые 15 минут
  • Python-скрипт B запрашивает несколько последних записей из базы данных каждые несколько минут

Оба используют ORM Django, работают на одном компьютере и используют локальную базу данных MySQL.

Проблема: B извлекает записи, за исключением самой последней, хотя A сохраняет ее * за 1023 * минуты раньше.

Я подозревал, что A не закрывает транзакцию, поэтому B видит базу данных без последней записи.Действительно, при проверке журналов MySQL я заметил, что commit для каждого INSERT происходит непосредственно перед next INSERT.

Даже если он должен быть избыточным, я добавил @commit_on_success декоратор для функции A , которая включает save(), но это не помогло.

Как я могу заставить Django (или MySQL ?!) совершить коммит сразу после save()?

ОБНОВЛЕНИЕ: Я обнаружил, что коммиты DO случаются - я ошибочно полагал, что они этого не делают, потому что Общий журнал запросов MySQL имеет разрешение 1 сек .В свете этой и другой новой информации я вновь задал вопрос здесь .

Ответы [ 2 ]

10 голосов
/ 11 августа 2011

Вы можете использовать декоратор commit_manually и вызывать его в любое время.

Прямо из документации :

from django.db import transaction

@transaction.commit_manually
def viewfunc(request):
    ...
    # You can commit/rollback however and whenever you want
    transaction.commit()
    ...

    # But you've got to remember to do it yourself!
    try:
        ...
    except:
        transaction.rollback()
    else:
        transaction.commit()

Это отвечает на вопрос, который вы задали , хотя мне интересно, может ли быть что-то еще на работе.

ПРИМЕЧАНИЕ: commit_manually устарел в 1.6 и удален в 1.8 .

0 голосов
/ 15 февраля 2016

Проблема вызвана тем, что MySQL по умолчанию имеет уровень изоляции транзакции REPEATABLE-READ.Это означает, что один и тот же запрос должен возвращать одинаковые значения.Изменения не вернутся.Здесь вы можете сделать две вещи:

  1. Установить уровень изоляции транзакции READ-COMMITTED в настройках.Как объяснено здесь .
  2. Принудительная фиксация, поэтому закройте транзакцию в сценарии B, чтобы при запуске новой транзакции вы видели все изменения до этой новой транзакции.Model.objects.update() делает свое дело.
...