8

私はsqlalchemyが初めてです。チュートリアルに従って、mysql db からの関係を持つ既存の db の自動マップを作成しました

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.IDtable1の列の1 つにマップされます。しかし、クエリと結合を使用しようとするtable1table2、「外部キー関係が見つかりません」というエラーが報告されます。私はこれら 2 つのテーブルの関係を知っているので、クラス インスタンスが作成された後にこの関係を宣言する方法はありますか? または、クエリ関数でこの関係を明示的に伝える方法はありますか? ありがとう!

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

onclausejoin SQLAlchemy のjoinメソッドのパラメーターを使用して明示的に行うことができます。パラメータは、SQLのonclauseJOIN と同様に使用されます。

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

クラスに外部キーを指定するだけで、データベースに外部キーが存在しないように指定することもできます。

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