Простой пример:
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:
statement = insert(Tablichka).values(quantity=2, price=100).returning(Tablichka)
obj = (await session.execute(statement)).scalar_one()
print(f"total_cost: wait 200, really {obj.total_cost}") # total_cost: wait 200, really 200
id = obj.id
statement = update(Tablichka).filter_by(id=id).values(quantity=4, price=100).returning(Tablichka)
obj = (await session.execute(statement)).scalar_one()
print(f"total_cost: wait 400, really {obj.total_cost}") # total_cost: wait 400, really 200
statement = select(Tablichka).filter_by(id=id)
obj = (await session.execute(statement)).scalar_one()
print(f"total_cost: wait 400, really {obj.total_cost}") # total_cost: wait 400, really 200
await session.commit()
async with async_session() as session:
statement = select(Tablichka).filter_by(id=id)
obj = (await session.execute(statement)).scalar_one()
print(f"\ntotal_cost: wait 400, really {obj.total_cost}") # total_cost: wait 400, really 400
if __name__ == "__main__":
import asyncio
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
loop.close()
После обновления я ожидаю получить пересчитанную сумму total_cost, но получаю старую сумму total_cost. Я получаю обновленные поля, кроме вычисляемых полей. При этом значение пересчитывается в базе данных. Это подтверждает запрос выбора в новом сеансе.
Как мне решить проблему?
На самом деле, у меня есть рабочий пример. Но я не понимаю, почему это работает:
async def run_create(session: AsyncSession):
statement = insert(Tablichka).values(quantity=2, price=100).returning(Tablichka)
obj = (await session.execute(statement)).scalar_one()
print(f"total_cost: wait 200, really {obj.total_cost}") # total_cost: wait 200, really 200
return obj.id
async def run_update(session: AsyncSession, id: int):
statement = update(Tablichka).filter_by(id=id).values(quantity=4, price=100).returning(Tablichka)
obj = (await session.execute(statement)).scalar_one()
print(f"total_cost: wait 400, really {obj.total_cost}") # total_cost: wait 400, really 400
async def run():
async with async_session() as session:
id = await run_create(session)
await run_update(session, id)
if __name__ == "__main__":
import asyncio
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
loop.close()
Но в моем проекте есть более сложный пример, в котором я не могу использовать свой рабочий пример. Мне нужно исправить мой сломанный пример.
Я использую следующие версии:
python = "^3.10"
sqlalchemy = "^2.0.35"
asyncpg = "^0.29.0"
greenlet = "^3.1.0"
Подробнее здесь: https://stackoverflow.com/questions/790 ... sqlalchemy
Я хочу получить вычисленное поле при возврате после обновления (sqlalchemy) ⇐ Python
Программы на Python
1730804893
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:
statement = insert(Tablichka).values(quantity=2, price=100).returning(Tablichka)
obj = (await session.execute(statement)).scalar_one()
print(f"total_cost: wait 200, really {obj.total_cost}") # total_cost: wait 200, really 200
id = obj.id
statement = update(Tablichka).filter_by(id=id).values(quantity=4, price=100).returning(Tablichka)
obj = (await session.execute(statement)).scalar_one()
print(f"total_cost: wait 400, really {obj.total_cost}") # total_cost: wait 400, really 200
statement = select(Tablichka).filter_by(id=id)
obj = (await session.execute(statement)).scalar_one()
print(f"total_cost: wait 400, really {obj.total_cost}") # total_cost: wait 400, really 200
await session.commit()
async with async_session() as session:
statement = select(Tablichka).filter_by(id=id)
obj = (await session.execute(statement)).scalar_one()
print(f"\ntotal_cost: wait 400, really {obj.total_cost}") # total_cost: wait 400, really 400
if __name__ == "__main__":
import asyncio
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
loop.close()
После обновления я ожидаю получить пересчитанную сумму total_cost, но получаю старую сумму total_cost. Я получаю обновленные поля, кроме вычисляемых полей. При этом значение пересчитывается в базе данных. Это подтверждает запрос выбора в новом сеансе.
Как мне решить проблему?
На самом деле, у меня есть рабочий пример. Но я не понимаю, почему это работает:
async def run_create(session: AsyncSession):
statement = insert(Tablichka).values(quantity=2, price=100).returning(Tablichka)
obj = (await session.execute(statement)).scalar_one()
print(f"total_cost: wait 200, really {obj.total_cost}") # total_cost: wait 200, really 200
return obj.id
async def run_update(session: AsyncSession, id: int):
statement = update(Tablichka).filter_by(id=id).values(quantity=4, price=100).returning(Tablichka)
obj = (await session.execute(statement)).scalar_one()
print(f"total_cost: wait 400, really {obj.total_cost}") # total_cost: wait 400, really 400
async def run():
async with async_session() as session:
id = await run_create(session)
await run_update(session, id)
if __name__ == "__main__":
import asyncio
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
loop.close()
Но в моем проекте есть более сложный пример, в котором я не могу использовать свой рабочий пример. Мне нужно исправить мой сломанный пример.
Я использую следующие версии:
python = "^3.10"
sqlalchemy = "^2.0.35"
asyncpg = "^0.29.0"
greenlet = "^3.1.0"
Подробнее здесь: [url]https://stackoverflow.com/questions/79011816/i-want-to-get-computed-field-in-returning-after-updating-sqlalchemy[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия