SQLAlchemy ORM: понимание преобразования/принуждения типов атрибутовPython

Программы на Python
Ответить
Anonymous
 SQLAlchemy ORM: понимание преобразования/принуждения типов атрибутов

Сообщение Anonymous »

Обратите внимание на следующий код и вывод консоли. Класс ORM TestTable имеет метку времени столбца (или атрибута), сопоставленную с типом datetime.
Когда я SELECT из базы данных, возвращаемый объект (см. переменную obj_from_db) type() этого атрибута — (как я и предполагал в TestTable) объявление класса).
Но когда я создаю его экземпляр напрямую (см. переменную obj_created), используя строку (общий формат ISO для даты и времени), тип не преобразуется (или не применяется принудительно). ), чтобы быть датой и временем. Несмотря на эту неконвертацию, вставка в базу данных работает корректно.
Хотелось бы знать:
  • Что делает SQLAlchemy, чтобы заполнить этот атрибут правильным типом () при ВЫБОРЕ из БД? Я думаю, что он где-то вызывает datetime.fromisoformat()...
  • Как я могу обеспечить соблюдение такое же поведение при ручном (напрямую) создании объекта ORM? Другими словами, как я могу указать SQLAlchemy всегда сохранять временную метку как (даже если она указана как str)?
#!/usr/bin/python3

from sqlalchemy import create_engine, select
from sqlalchemy.orm import Session
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from datetime import datetime

# declarative base class
class Base(DeclarativeBase):
pass

# declare a object to be mapped to a table in database
class TestTable(Base):
__tablename__ = "test_table"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
name: Mapped[str]
timestamp: Mapped[datetime]
version: Mapped[int]

# create a database engine
engine = create_engine('postgresql://@/my_db', echo=False)

Base.metadata.create_all(engine)

with Session(engine) as session:
# create object 'directly'
obj_created = TestTable(name='new one', timestamp='2024-12-27 13:49:56', version=7)

# put it on session
session.add(obj_created)

# print the type of the obj_created timestamp attribute
print('type(obj_created.timestamp) (object created): ', type(obj_created.timestamp))

# commit objects in this session to the database
session.commit()

# select one item from database (any)
obj_from_db = session.scalars(select(TestTable)).first()

if obj_from_db is not None:
# print the type of the obj_from_db timestamp attribute
print('type(obj_from_db.timestamp) (object from DB): ', type(obj_from_db.timestamp))


Вывод на консоль:
type(obj_created.timestamp) (object created):
type(obj_from_db.timestamp) (object from DB):


Подробнее здесь: https://stackoverflow.com/questions/792 ... nforcement
Ответить

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

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

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

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

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