SQLAlchemy: отображение объектов потеряно после фиксации? - PullRequest
2 голосов
/ 23 июня 2009

У меня есть простая проблема в SQLAlchemy. У меня есть одна модель в таблице, давайте назовем ее Model1 здесь. Я хочу добавить строку в эту таблицу и получить автоинкрементный ключ, чтобы я мог создать другую модель и использовать этот ключ. Это не ошибочный дизайн базы данных (соотношение 1: 1 и т. Д.). Мне просто нужен этот ключ в другой таблице, потому что другая таблица переносится на удаленный хост, и мне нужны соответствующие ключи, чтобы серверы понимали друг друга. Между этими двумя таблицами больше не будет локальной ссылки, и из-за этого также невозможно создать отношения.

Рассмотрим следующий код:

object1 = model.Model1(param)
DBSession.add(object1)

# if I do this, the line below fails with an UnboundExecutionError.
# and if I dont do this, object1.id won't be set yet
#transaction.commit()

object2 = model.AnotherModel(object1.id) #id holds the primary, autoincremented key

Хотелось бы, чтобы мне даже не пришлось совершать "вручную". По сути, я бы хотел добиться того, чтобы «Model1» постоянно росла, увеличивая первичный ключ Model.id. AnotherModel - это всего лишь небольшая часть Model1, которая еще не была обработана. Конечно, я мог бы добавить флаг «Model1», логическое поле в таблице, чтобы пометить уже обработанные элементы, но я надеялся, что в этом нет необходимости.

Как мне заставить работать мой код выше?

Greets

Tom

Ответы [ 3 ]

3 голосов
/ 24 июня 2009

Пара вещей:

  • Не могли бы вы объяснить, с чем связана переменная transaction?
  • Какой именно оператор вызывает ошибку UnboundExecutionError?
  • Пожалуйста, предоставьте полное сообщение об исключении, включая трассировку стека.
  • «Нормальным» в этом случае было бы позвонить DBSession.flush(). Вы пробовали это?

Пример:

object1 = Model1(param)
DBSession.add(object1)
DBSession.flush()
assert object1.id != None # flushing the session populates the id

object2 = AnotherModel(object1.id)

Отличное объяснение сеанса SA и того, что делает flush(), см. В Использование сеанса .

По сути, flush() приводит к тому, что ожидающие экземпляры становятся постоянными - это означает, что новые объекты вставляются в таблицы базы данных. flush() также ОБНОВЛЯЕТ таблицы со значениями для экземпляров, которые сеанс отслеживает с изменениями.

commit() всегда выдает flush() first.

В рамках транзакции вы можете выполнить сброс несколько раз. Каждый flush () вызывает UPDATE и / или INSERT в базе данных. Вся транзакция может быть зафиксирована или отменена.

2 голосов
/ 25 июня 2009

если вы хотите получить новые идентификаторы первичного ключа для генерации без фиксации, просто вызовите session.flush (). Это будет отправлять все ожидающие данные в базу данных в рамках текущей транзакции.

1 голос
/ 23 июня 2009

Я использовал это только с ForeignKeys, так что во втором случае вы бы предпочли model.AnotherModel (model1 = object1), и тогда он просто работал (tm) Поэтому я подозреваю, что это может быть проблемой с вашими моделями, так что, возможно, вы тоже можете их опубликовать?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...