2011-09-07 97 views
1

如何在SqlAlchemy ORM中进行动态查询(如果它是一个正确的名称)。SqlAlchemy:动态查询

我用SqlAlchemy作为数据库的抽象,用python代码查询,但是如果我需要动态生成这些查询,不仅设置查询参数如“id”?

例如,我需要从列表(表名,列名,连接列)生成链接三个表,如“组织”,“人员”,“职员”的查询。我如何正确地做到这一点?

例如,我的意思是这个列表: [{'table':'organization','column':'staff_id'}, {'table':'staff','column':'id'} ]

和输出例如可以包含: organisation.id,organisation.name,organisation.staff_id,staff.id,staff.name (名称列仅呈现输出,因为我需要简单的例子,recieving所有表的列和数组必须只设置连接)

+0

“我需要从”str“元素(表名,列名,连接列)数组中生成查询”。这没有什么意义。请举一个例子。 –

+1

嗯..你已经向我们展示了* input *,但它可能会有助于向我们展示预期的输出,无论是等价的sqlalchemy语句还是生成的SQL。我可以想出几种解释你的意见的方式,每种方式的意思都不一样。 – SingleNegationElimination

+0

“我的意思是这个数组”...不是一个数组。这是一个字典列表。 –

回答

1

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

1

还没有测试过,但它与SQLAlchemy的ORM,你可以链接在一起,如:

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:[email protected]: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)