10

外部キーを持つ既存の (SQLite) データベースから始めて、SQLAlchemy は自動的に関係を構築できますか?

SQLAlchemy クラスは、 を介して自動的に作成され__table_args__ = {'autoload': True}ます。

目標は、すべてのリレーションシップを 1 つずつ手動で追加する必要なく (つまり、 and を使用せずに)、関連するテーブルからデータに簡単にアクセスできるようにすることsqlalchemy.orm.relationship()ですsqlalchemy.orm.backref

4

2 に答える 2

10

[更新] SQLAlchemy 0.9.1 の時点で、それを行うためのAutomap 拡張機能があります。

SQLAlchemy < 0.9.0 では、sqlalchemy リフレクションを使用できます。

SQLAlchemy リフレクションは、テーブル間の外部/主キーの関係を読み込みます。ただし、マップされたクラス間の関係は作成しません。実際には、リフレクションはマップされたクラスを作成しません。マップされたクラス名を指定する必要があります。

実際、外部キーをロードするためのリフレクション サポートは、優れたヘルパーで時間の節約になるツールだと思います。これを使用すると、結合に使用する列を指定しなくても、結合を使用してクエリを作成できます。

from sqlalchemy import *
from sqlalchemy import create_engine, orm
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship



metadata = MetaData()
Base = declarative_base()
Base.metadata = metadata

db = create_engine('<db connection URL>',echo=False)
metadata.reflect(bind=db)

cause_code_table = metadata.tables['cause_code']
ndticket_table = metadata.tables['ndticket']

sm = orm.sessionmaker(bind=db, autoflush=True, autocommit=True, expire_on_commit=True)
session = orm.scoped_session(sm)

q = session.query(ndticket_table,cause_code_table).join(cause_code_table)
for r in q.limit(10):
    print r

また、リフレクションを使用して既存のデータベースにクエリを実行していたとき、マップされたクラス名、テーブル バインディング、リレーションのみを定義する必要がありましたが、これらのリレーションのテーブル列を定義する必要はありませんでした。

class CauseCode(Base):
    __tablename__ = "cause_code"

class NDTicket(Base):
    __tablename__ = "ndticket"
    cause_code = relationship("CauseCode", backref = "ndticket")


q = session.query(NDTicket)
for r in q.limit(10):
    print r.ticket_id, r.cause_code.cause_code

全体的な SQLAlchemy リフレクションはすでに強力なツールであり、時間を節約できるため、リレーションを手動で追加することは私にとって小さなオーバーヘッドです。

既存の外部キーを使用してマップされたオブジェクト間の関係を追加する機能を開発する必要がある場合は、 inspector でリフレクションを使用することから始めます。get_foreign_keys() メソッドを使用すると、関係を構築するために必要なすべての情報 (参照されるテーブル名、参照される列名、およびターゲット テーブル内の列名) が得られます。そして、この情報を使用して、関係を持つプロパティをマップされたクラスに追加します。

insp = reflection.Inspector.from_engine(db)
print insp.get_table_names()
print insp.get_foreign_keys(NDTicket.__tablename__)
>>>[{'referred_table': u'cause_code', 'referred_columns': [u'cause_code'], 'referred_schema': None, 'name': u'SYS_C00135367', 'constrained_columns': [u'cause_code_id']}]
于 2013-01-18T16:28:04.060 に答える
2

SQLAlchemy 0.9.1 の時点で、(今のところ実験的な) Automap 拡張機能はまさにそれを行うようです: http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/automap.html

于 2014-07-09T14:31:24.763 に答える