2014-09-21 66 views
7

我是新来的sqlalchemy。我按照教程创建从一个MySQL关系的现有数据库的自动映射数据库是否可以在通过SqlAlchemy中的automap创建类之后声明关系

from sqlalchemy import create_engine, MetaData, Column, Table, ForeignKey 
from sqlalchemy.ext.automap import automap_base, generate_relationship 
from sqlalchemy.orm import relationship, backref 
from config import constr, mytables 

def _gen_relationship(base, direction, return_fn, 
        attrname, local_cls, refferred_cls, **kw): 
    return generate_relationship(base, direction, return_fn, attrname, local_cls, refferred_cls, **kw) 

engine = create_engine(constr) 
metadata = MetaData() 
metadata.reflect(engine, only=mytables) 
Base = automap_base(metadata=metadata) 
Base.prepare(engine, reflect=True, generate_relationship=_gen_relationship) 
Tableclass1 = Base.classes.table1 
Tableclass2 = Base.classes.table2 

Table2.ID映射到table1的一列。但是当我尝试使用查询并加入table1table2时,它报告错误,指出“无法找到任何外键关系”。既然我知道这两个表的关系,那么在创建类实例之后,我有没有办法声明这种关系呢?或者有没有办法明确告诉查询函数中的这种关系? 谢谢!

回答

0

您可以通过使用onclause联接SQLAlchemy的join方法的明细表明确地做到这一点。 onclause参数与SQL的JOIN类似使用。

sqlalchemy.orm.join(table1, table2, onclause=table2.ID == table1.your_attribute) 

您还可以通过状态只是在陈述中的类外键绕过数据库外键的存在:

Column('ID', Integer, ForeighKey('table1.your_attribute')) 
3

虽然可以做到这一点中提到的查询中@mpolednik ,如果我正确地阅读你的问题,理想的解决方案是在你的课堂中声明关系以便重复使用。

它可以简单地实现预宣称要使用,像这样的类:

from sqlalchemy.ext.automap import automap_base 
from sqlalchemy.orm import Session, relationship 
from sqlalchemy import create_engine, Column, String 

Base = automap_base() 

engine = create_engine("postgresql://user:[email protected]:5432/mydb") 

# pre-declare User for the 'user' table 
class User(Base): 
    __tablename__ = 'user' 

    # override schema elements like Columns 
    oname = Column('originalname', String) 

    # and a relationship. I name it 'weird' because in my database schema 
    # this relationship makes absolutely no sense, but it does demonstrate 
    # the point 
    weird = relationship("usergroup", 
         foreign_keys='usergroup.id', 
         primaryjoin='and_(usergroup.id==User.id)') 

Base.prepare(engine, reflect=True) 
session = Session(engine) 

# Test this by querying the User table and then following the relationship 
u = session.query(User).filter(User.oname == 'testuser').one() 
print (u.oname) 
for g in u1.weird: 
    print g.name 

看到这里的文档(包括另一个例子):http://docs.sqlalchemy.org/en/latest/orm/extensions/automap.html?highlight=automap#specifying-classes-explicitly

相关问题