Как сделать динамические запросы в ORM (SqlAlchemy ORM) (если это правильное имя для них).
Я использовал SqlAlchemy как абстракцию для базы данных с запросами в коде python, но что делать, если мне нужно генерировать эти запросы динамически, а не только устанавливать параметры запроса как "id"?
Например, мне нужно создать запрос из списка (имена таблиц, имена столбцов, объединенные столбцы), которые связывают три таблицы типа "организация", "люди", "персонал". Как я могу сделать это правильно?
Например, я имел в виду этот список: [{'table': 'organization', 'column': 'staff_id'}, {'table': 'staff', 'column': 'id'}]
И вывод, например, может содержать: organisation.id, organisation.name, organisation.staff_id, staff.id, staff.name (столбец имен представлен только на выходе, потому что мне нужен простой пример, получение всех столбцов таблиц, а массив должен просто установите соединения)
Вы можете использовать mapper
в результате вызова sqlalchemy.sql.join
и/или sqlalchemy.select
. Это примерно эквивалентно использованию mapper
в представлении базы данных; вы можете запросить такие классы естественно, но не обязательно создавать новые записи. Вы также можете использовать sqlalchemy.orm.column_property
для сопоставления вычисленных значений с атрибутами объектов. Когда я прочитаю ваш вопрос, комбинация этих трех методов должна соответствовать вашим потребностям.
Не тестировали, но с помощью ORM SQLAlchemy вы можете связать таблицы вместе, например:
from sqlalchemy import create_engine, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, ForeignKey
from sqlalchemy.orm import relationship
from asgportal.database import Session
Engine = create_engine('mysql+mysqldb://user:password@localhost:3306/mydatabase', pool_recycle=3600)
Base = declarative_base(bind=Engine)
session = Session()
session.configure(bind=Engine)
class DBOrganization(Base):
__tablename__ = 'table_organization'
id = Column(Integer(), primary_key=True)
name = Column(ASGType.sa(ASGType.STRING))
class DBEmployee(Base):
__tablename__ = 'table_employee'
id = Column(Integer(), primary_key=True)
name = Column(String(255))
organization_id = Column(Integer(), ForeignKey('table_organization.id'))
# backref below will be an array[] unless you specify uselist=False
organization = relationship(DBOrganization, backref='employees')
Base.metadata.create_all()
# From here, you can query:
rs = session.query(DBEmployee).join(DBEmployee.organization).filter(DBOrganization.name=='my organization')
for employees in rs:
print '{0} works for {1}'.format(employees.name,employees.organization.name)