Я использую sqlalchemy 1.3.0 с postgres 11. Я пытаюсь использовать INSERT
с ON CONFLICT DO UPDATE ... RETURNING *
для создания экземпляра моей модели.
class Model(Base):
__tablename__ = 'mytable'
pk = Column(String(64), primary_key=True)
col2 = Column(String(64))
@classmethod
def upsert(cls, pk, col2, session):
return session.query(cls).from_statement(
text(
"""
INSERT INTO {} (pk, col2) VALUES (:pk, :col2)
ON CONFLICT (pk) DO UPDATE SET col2=EXCLUDED.col2 RETURNING *;
""".format(cls.__tablename__)
)
).params(pk=pk, col2=col2).one()
obj1 = Model.upsert(1, 'one', session)
obj2 = Model.upsert(1, 'two', session)
print(obj2.col2) ----> outputs "one"
session.commit()
print(obj2.col2) ----> outputs "two"
Второй upsert выдает правильную команду для базы данных, но при печати атрибута col2 возвращаемого объекта отображается значение столбца, который был вставлен во время first upsert. Затем, если я сделаю session.commit()
, объект волшебным образом обновится, чтобы показать новое значение. Что мне не хватает? Я хочу, чтобы объект, возвращаемый функцией, отражал значения, до которых была обновлена строка, без необходимости выполнения коммита, потому что я хочу, чтобы это наряду с некоторыми другими вещами происходило в транзакции.