0
我實現了連接表繼承,如問題SQLAlchemy Inheritance中所述。儘管有棘手的ForeignKey關係,SQLAlchemy類如何正確繼承?
有以下情況:我想有一個
- 用戶它有一個
emailaddress
- 別名其別名分配 -
emailaddress
到另一電子郵件地址
爲了保持emailaddress
的獨特性,我們的想法是讓這兩個類繼承Emailaddress
使用加入表繼承。這些例子可以實現以下類別:
Emailaddress
EmailaddressUser(Emailaddress)
EmailaddressAlias(Emailaddress)
繼承實現以下用途:
u = EmailaddressUser(name="Testuser", emailaddress="[email protected]")
=>我不需要在beforeh之前實例化一個Emailaddress
和 - 便於使用。
不幸的是,同樣的事情不適用於EmailaddressAlias
,雖然唯一的區別是第二個屬性是一個ForeignKey相同的屬性emailaddress
。因此我需要指定inherit_condition。但是:
a = EmailaddressAlias (
real_emailaddress="[email protected]",
alias_emailaddress="[email protected]"
)
- >在將數據添加到數據庫時引發IntegrityError。這裏查看完整的例子:
import sqlalchemy as sa
import sqlalchemy.orm as orm
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Emailaddress(Base):
__tablename__ = 'emailaddresses'
emailaddress = sa.Column(sa.String, primary_key=True)
emailtype = sa.Column(sa.String, nullable=False)
__mapper_args__ = {'polymorphic_on': emailtype}
class EmailaddressUser(Emailaddress):
__tablename__ = 'emailaddress_users'
__mapper_args__ = {'polymorphic_identity': 'user'}
emailaddress = sa.Column(
sa.String,
sa.ForeignKey('emailaddresses.emailaddress'),
primary_key=True)
name = sa.Column(sa.String, nullable=False)
class EmailaddressAlias(Emailaddress):
__tablename__ = 'emailaddresses_alias'
alias_emailaddress = sa.Column(
sa.String,
sa.ForeignKey('emailaddresses.emailaddress'),
primary_key=True)
real_emailaddress = sa.Column(
sa.ForeignKey('emailaddresses.emailaddress'),
nullable=False)
__mapper_args__ = {
'polymorphic_identity': 'alias',
'inherit_condition':Emailaddress.emailaddress==alias_emailaddress}
if __name__ == '__main__':
engine = sa.create_engine ('sqlite:///email.sqlite', echo=True)
Base.metadata.bind = engine
Base.metadata.create_all()
Session = orm.sessionmaker (engine)
session = Session()
# add user (works):
u = EmailaddressUser(name="Testuser", emailaddress="[email protected]")
session.add(u)
session.commit()
# --> INSERT INTO emailaddresses (emailaddress, emailtype) VALUES (?, ?)
# --> ('[email protected]', 'user')
# 'emailaddress' is inserted correctly
# add alias (throws an IntegrityError):
a = EmailaddressAlias (
real_emailaddress="[email protected]",
alias_emailaddress="[email protected]"
)
session.add(a)
session.commit()
# --> INSERT INTO emailaddresses (emailtype) VALUES (?)' ('alias',)
# 'emailaddress' is missing! => IntegrityError
'EmailaddressAlias'有4個屬性,包括'emailaddress'和'Emailaddress',繼承'name'你不傳遞給新的對象的構造函數。所以這裏預計會出現異常。我相信從Emailaddress繼承「EmailaddressAlias」是一個錯誤。試着描述你的意圖,以獲得更好的幫助。 –
我添加了一些詞語來闡明我的意圖。構思您的評論:'name'不是從'Emailaddress'繼承的。這只是'EmailaddressUser'的一個屬性。 –
經過一些測試後,我認爲這是SQLAlchemy中的一個錯誤,原因如下:在'EmailaddressAlias':'alias_emailaddress'內重命名爲'emailaddress'(也在'inherit_condition'內)解決了這個問題。但是'inherit_condition'應該允許不同的命名! –