從具有外鍵的現有(SQLite)數據庫開始,SQLAlchemy可以自動生成relationships?SQLAlchemy可以自動從數據庫模式創建關係嗎?
SQLAlchemy類是通過__table_args__ = {'autoload': True}
自動創建的。
目標是輕鬆訪問相關表中的數據,而無需手動添加所有關係(即不使用sqlalchemy.orm.relationship()
和sqlalchemy.orm.backref
)。
從具有外鍵的現有(SQLite)數據庫開始,SQLAlchemy可以自動生成relationships?SQLAlchemy可以自動從數據庫模式創建關係嗎?
SQLAlchemy類是通過__table_args__ = {'autoload': True}
自動創建的。
目標是輕鬆訪問相關表中的數據,而無需手動添加所有關係(即不使用sqlalchemy.orm.relationship()
和sqlalchemy.orm.backref
)。
[更新]從SQLAlchemy 0.9.1開始,有Automap extension這樣做。
對於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的反射已經是功能強大的工具,節省了我的時間,所以手動添加關係對我來說是小的開銷。
如果我將不得不開發使用現有外鍵在映射對象之間添加關係的功能,我將從使用reflection with 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']}]
由於SQLAlchemy中的0.9.1的(目前實驗)自動映射擴展似乎做到這一點:http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/automap.html