我使用declarative_base()並試圖找出在使用多對多關係時如何強制執行懶惰內部聯接。在sqlalchemy中強制使用多對多關係進行內部聯接
我在MySQL和InnoDB中定義了具有外鍵約束的表。
users: userid, name
permissions: permissionid, name
users_permissions: userid, permissionid
我正在使用metadata.reflect()
來加載我的數據庫。
class User_Perm(Base):
__table__ = Base.metadata.tables['users_permissions']
class User(Base):
__table__ = Base.metadata.tables['users']
permissions = orm.relationship('Permission',
secondary=User_Perm.__table__,
order_by='Perm.name',
innerjoin=True,
lazy=True,
)
class Permission(Base):
__table__ = Base.metadata.tables['permissions']
每當我選擇
u = Session().query(User).filter(User.name == 'myuser').first()
u.permissions
由MySQL服務器收到的查詢是:
SELECT permissions.permissionid AS permissions_permissionid,
permissions.name AS permissions_name
FROM permissions, users_permissions
WHERE ? = users_permissions.userid
AND permissions.permissionid = users_permissions.permissionid
ORDER BY permissions.name
正如我們所看到的,FROM permissions, users_permissions
不是內連接。我可以強制執行此操作而不需要使用lazy=False
,因爲如果我這樣做,級聯效果將會加載太多的信息,因爲permissions
也與另一個表(示例中未提及)有關係,並且users
也與其他表(再次,在例子中沒有提到)。我想爲所有類使用相同的模板關係。
編輯:上下文我想複製所有的SQL查詢來匹配那些從當前系統。我正嘗試從oursql
遷移到sqlalchemy orm
。
如果您需要兩個應用程序之間的字符匹配,一個使用手寫查詢,另一個使用ORM,則您會感到失望。 SQLAlchemy ORM當然可以複製結構非常相似的查詢,但是一些特性(如關係延遲加載)本質上沒有空間讓查詢充分定製。如前所述,您需要比較MySQL的EXPLAIN輸出和INNER JOIN vs.隱式連接以驗證等效性能。 – zzzeek