SQLAlchemy flush () и получить вставленный идентификатор?



Я хочу сделать что-то вроде этого:



f = Foo(bar='x')
session.add(f)
session.flush()

# do additional queries using f.id before commit()
print f.id # should be not None

session.commit()


но f.id нет, когда я пытаюсь это сделать. Как я могу заставить это работать?



- Dan

866   6  

6 ответов:

ваш пример кода должен был работать как есть. Sqlalchemy должен предоставлять значение для f.id, предполагая, что это автогенерирующий столбец первичного ключа. атрибуты первичного ключа заполняются непосредственно в процессе flush() по мере их создания, и не требуется никакого вызова commit (). Поэтому ответ здесь заключается в деталях вашего сопоставления, если есть какие-либо нечетные причуды используемого бэкэнда (например, SQLite не генерирует целочисленные значения для составного первичного ключа) и/или что излучаемый SQL говорит, когда вы включаете echo.

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

В настоящее время или по состоянию на sqlalchemy .6+, есть очень простое решение (я не знаю, существует ли это в предыдущей версии, хотя я представляю, как это):

сессии.обновить()

Итак, ваш код будет выглядеть примерно так:

f = Foo(bar=x)
session.add(f)
session.flush()
# At this point, the object f has been pushed to the DB, 
# and has been automatically assigned a unique primary key id

f.id
# is None

session.refresh(f)
# refresh updates given object in the session with its state in the DB
# (and can also only refresh certain attributes - search for documentation)

f.id
# is the automatically assigned primary key ID given in the database.

вот как это сделать.

спасибо всем. Я решил свою проблему, изменив сопоставление столбцов. Для меня, Это.

происхождения: id = Column('ID', Integer, primary_key=True, nullable=False)

после изменения: id = Column('ID', Integer, primary_key=True, autoincreament=True, nullable=True)

затем session.flush()
print(f.id)

ОК!

в отличие от ответа, данного dpb, обновление не требуется. после того, как вы очистите, вы можете получить доступ к полю id, sqlalchemy автоматически обновляет идентификатор, который автоматически генерируется на бэкэнде

Я столкнулся с этой проблемой и понял точную причину после некоторого исследования, моя модель была создана с id как integerfield и в моей форме id был представлен с hiddenfield( так как я не хотел показывать id в моей форме). Скрытое поле по умолчанию представлено в виде текст. как только я изменил форму на integerfield с widget=hiddenInput()) проблема была решена.

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

вы должны попробовать использовать session.save_or_update(f) вместо session.add(f).

Comments

    Ничего не найдено.