Как я могу преобразовать результаты запроса Sqlalchemy ORM в одну объединенную таблицу, включающую отношения? - PullRequest
0 голосов
/ 08 июля 2019

Я проснулся в существующем API Python для базы данных веб-приложения и хотел бы предоставить пользователям возможности форматирования результатов своих запросов.В некоторых случаях подходит JSON, а в других CSV.API построен на декларативном ORM SQLAlchemy, и запросы в системе обычно возвращают экземпляры ORM или списки экземпляров вместе с их связями.Преобразовать это в JSON очень просто, однако у меня возникают проблемы с извлечением табличного представления для преобразования результатов в CSV.Используя основные операции SQLAlchemy или простой SQL, легко вернуть объединенное табличное представление.Я знаю, что за кулисами SQLAlchemy создает необходимые операторы SQL и объединяет их для выполнения того, что я запрашиваю, но оно скрыто за маппером.

Учитывая, что API, с которым я работаю, уже настроен для запроса всегодекларативно, используя классы ORM, как я могу получить обратно строки, которые были возвращены базой данных до того, как SQLAlchemy выполнит свою магию, чтобы отобразить все обратно объектам?

user_addresses = Table("user_addresses", Base.metadata,
    Column("user_id", Integer, ForeignKey("user.id")),
    Column("address_id", Integer, ForeignKey("address.id"))
)

class User(Base):
    __tablename__ = "user"
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String)
    addresses = relationship("Address", secondary=user_addresses, back_populates="users")


class Address(Base):
    __tablename__ = "address"
    id = Column(Integer, primary_key=True, autoincrement=True)
    number = Column(Integer)
    street = Column(String)
    city = Column(String)
    state = Column(String)
    zip = Column(Integer)
    users = relationship("User", secondary=user_addresses, back_populates="addresses")


## configure session, engine, etc.
# get all relationships loaded together
statement = session.query(User).options(joinedload("*"))
# normal orm classes
results = statement.all()
# I want something like
flat_results = statement.table()

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

1 Ответ

1 голос
/ 09 июля 2019

Дайте возможный ответ на мой собственный вопрос, так что если у вас есть что-то лучше, не стесняйтесь отвечать.

Самый простой способ, который я нашел для достижения этой цели, - это извлечьфактический оператор SQL, который будет выполнен Session и будет выполнен непосредственно с использованием метода execute:

statement = session.query(User).options(joinedload("*"))
results = session.execute(str(statement))
colnames = results.keys()
rows = results.fetchall()

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

Редактировать : Как отмечает @ IljaEverilä, лучше вызвать Query.statement, чтобы получить окончательные команды SQL со всеми правильными подстановками аргументов иБэкэнд определенной функциональности:

statement = session.query(User).options(joinedload("*")).statement
results = session.execute(statement)
colnames = results.keys()
rows = results.fetchall()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...