我有一個父Employee表和一個Child Engineer表。從客戶角度來看,我只想與Employee模型進行交互。這對於READ和DELETE很容易實現,但在嘗試更新或插入時會出現問題。SQLAlchemy級聯多態列更新
的sqlalchemy docs狀態:
警告
目前,只有一個識別器字段可以被設置爲,通常在分層結構中的基最類。 「級聯」多態列還不被支持。
所以看起來默認情況下這不起作用。我正在尋找如何完成這項工作的想法。
這是一個使用postgres和psycopg2的完整測試設置。 SQL可能與其他SQL數據庫一起工作,但我測試了其他任何其他SQL數據庫。
SQL腳本來創建測試數據庫(TESTDB)和表(員工,工程師):
CREATE DATABASE testdb;
\c testdb;
CREATE TABLE employee(
id INT PRIMARY KEY NOT NULL,
name TEXT,
type TEXT
);
CREATE TABLE engineer(
id INT PRIMARY KEY NOT NULL,
engineer_name TEXT,
employee_id INT REFERENCES employee(id)
ON UPDATE CASCADE
ON DELETE CASCADE
);
的Python測試腳本:
AS-是INSERT測試將失敗,但DELETE將通過。如果您更改代碼(註釋/取消註釋)以使用子工程師模型,它將通過這兩種情況。
import sqlalchemy as sa
import sqlalchemy.orm as orm
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import (
Column,
ForeignKey,
Integer,
Text,
)
Base = declarative_base()
class Employee(Base):
__tablename__ = 'employee'
id = Column(Integer, primary_key=True)
name = Column(Text(), default='John')
type = Column(Text, default='engineer')
__mapper_args__ = {
'polymorphic_identity':'employee',
'polymorphic_on':type,
'with_polymorphic': '*',
}
class Engineer(Employee):
__tablename__ = 'engineer'
id = Column(Integer, ForeignKey('employee.id',
ondelete='CASCADE', onupdate='CASCADE'), primary_key=True)
engineer_name = Column(Text(), default='Eugine')
__mapper_args__ = {
'polymorphic_identity':'engineer',
}
def count(session, Model):
query = session.query(Model)
count = len(query.all())
return count
url = 'postgresql+psycopg2://[email protected]/testdb'
engine = sa.create_engine(url)
Base.metadata.bind = engine
Base.metadata.create_all()
Session = orm.sessionmaker(engine)
session = Session()
if __name__ == '__main__':
id=0
print '#'*30, 'INSERT', '#'*30
id += id
# I only want to interact with the Employee table
e = Employee(id=id)
# Use the child model to see the INSERT test pass
# e = Engineer(id=id)
session.add(e)
session.commit()
print 'pass' if count(session, Employee) == count(session, Engineer) else 'fail'
print '#'*30, 'DELETE', '#'*30
# e = session.query(Employee).first()
session.delete(e);
session.commit();
print 'pass' if count(session, Employee) == count(session, Engineer) else 'fail'
session.flush()
有關如何通過sqlalchemy模型定義完成此操作而不必使用顯式控制器代碼的任何想法?
謝謝!
編輯 嗯,我沒有得到任何這個愛。任何人有關於如何完成這個與控制器代碼的想法?