8

我是 sqlalchemy 的新手。我已按照教程创建与 mysql 数据库有关系的现有数据库的自动映射

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's 列之一。但是当我尝试使用 query 和 join table1andtable2时,它报告错误说“找不到任何外键关系”。既然我知道这两个表的关系,我有没有办法在创建类实例后声明这种关系?或者有没有办法在查询函数中明确地告诉这种关系?谢谢!

4

2 回答 2

2

虽然可以在@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:pass@localhost: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

于 2015-07-06T15:52:50.740 回答
0

onclause您可以通过使用join SQLAlchemy 方法的参数来明确地做到这一点joinonclause参数的使用与 SQL 的 JOIN类似,例如

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

您还可以通过简单地在类中声明外键来声明绕过数据库中外键的存在:

Column('ID', Integer, ForeighKey('table1.your_attribute'))
于 2015-05-03T16:54:16.230 回答