Я использую sqlalchemy и хочу получить новые значения вычисляемого поля при возврате после обновления.Python

Программы на Python
Ответить
Anonymous
 Я использую sqlalchemy и хочу получить новые значения вычисляемого поля при возврате после обновления.

Сообщение Anonymous »

Простой пример:

Код: Выделить всё

from sqlalchemy import Column, Integer, Computed, update, insert, select
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
from sqlalchemy.orm import DeclarativeBase, declared_attr

engine = create_async_engine(url="postgresql+asyncpg://db_user:db_pass@localhost:54320/db_name")
async_session = async_sessionmaker(bind=engine)

class BaseTable(DeclarativeBase):
@declared_attr
def __tablename__(cls) -> str:
return cls.__name__.lower()

class Tablichka(BaseTable):
id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
quantity = Column(Integer, nullable=False)
price = Column(Integer, nullable=False)
total_cost = Column(Integer, Computed("quantity * price"))  # Attention!
Я хочу обновить строку с помощью запроса orm. Мне нужно получить результат, поэтому я использую return:

Код: Выделить всё

async def run():
async with async_session() as session:
# Inserting
statement = insert(Tablichka).values(quantity=2, price=100).returning(Tablichka)
obj = (await session.execute(statement)).scalar_one()
# total_cost: wait 200, really 200
print(f"total_cost: wait 200, really {obj.total_cost}")
id = obj.id

# Updating
statement = update(Tablichka).filter_by(id=id).values(quantity=4, price=100).returning(Tablichka)
obj = (await session.execute(statement)).scalar_one()
# total_cost: wait 400, really 200
print(f"total_cost: wait 400, really {obj.total_cost}")

# Selecting
statement = select(Tablichka).filter_by(id=id)
obj = (await session.execute(statement)).scalar_one()
# total_cost: wait 400, really 200
print(f"total_cost: wait 400, really {obj.total_cost}")

await session.commit()

async with async_session() as session:
# Selecting in another session
statement = select(Tablichka).filter_by(id=id)
obj = (await session.execute(statement)).scalar_one()
# total_cost: wait 400, really 400
print(f"\ntotal_cost: wait 400, really {obj.total_cost}")

if __name__ == "__main__":
import asyncio

loop = asyncio.get_event_loop()
loop.run_until_complete(run())
loop.close()
После обновления я ожидаю получить пересчитанную сумму total_cost, но получаю старую сумму total_cost. Я получаю обновленные поля, кроме вычисляемых полей. При этом значение пересчитывается в базе данных. Это подтверждает запрос выбора в новом сеансе.
Я использую следующие версии:

Код: Выделить всё

python = "^3.10"
sqlalchemy = "^2.0.35"
asyncpg = "^0.29.0"
greenlet = "^3.1.0"
Как решить проблему?

Подробнее здесь: https://stackoverflow.com/questions/790 ... ning-after
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»