SqlAlchemy:动态查询

2 投票
2 回答
3571 浏览
提问于 2025-04-17 01:43

如何在SqlAlchemy ORM中创建动态查询(如果这个名字是正确的话)。

我使用SqlAlchemy来作为数据库的抽象层,通过Python代码来进行查询,但如果我需要动态生成这些查询,而不仅仅是设置像“id”这样的查询参数,该怎么办呢?

举个例子,我需要从一个列表中生成查询,这个列表包含了三个表的名称,比如“organisation”、“people”和“staff”,以及它们的列名。我要怎么正确地做到这一点呢?

比如,我指的这个列表是: [{'table':'organisation', 'column':'staff_id'}, {'table':'staff', 'column':'id'}]

而输出的结果可能包含: organisation.id, organisation.name, organisation.staff_id, staff.id, staff.name (这里的name列只是为了举个简单的例子,实际上我需要获取所有表的列,而这个数组只是用来设置连接关系的)

2 个回答

1

我还没测试过,不过使用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)
1

你可以在调用 sqlalchemy.sql.join 或者 sqlalchemy.select 的结果上使用 mapper。这大致相当于在数据库视图上使用 mapper;你可以很自然地对这些类进行查询,但不一定能创建新的记录。你还可以使用 sqlalchemy.orm.column_property 将计算得到的值映射到对象的属性上。根据我对你问题的理解,结合这三种技术应该能满足你的需求。

撰写回答