私はこの質問を書くのに苦労しました。それは複雑で珍しいユースケースになるかもしれません。SQLAlchemyのクラス継承階層をサブクラス化
共通のデータベーススキーマとコア機能を維持する1つのプロジェクトに複数のORMクラスを定義しました。たとえば、これがmodel.email
モジュールであるとします。
from sqlalchemy import Column, Index, ForeignKey
from sqlalchemy import Boolean, Integer, Text
from . import Base
class CampaignDB(Base):
"""
Note: this basic database mapper class is expected to be extended.
When sub-classing, be mindful to override mappings to other extended classes.
"""
__tablename__ = 'campaigns'
audience_id = Column(Integer, ForeignKey("audiences.id"))
active = Column(Boolean)
name = Column(Text)
これらのORMクラスは、他のいくつかのプロジェクトにパッケージとしてインポートされます。場合によっては、これらのORMクラスは、追加機能を提供するためにサブクラス化されています。たとえば、CampaignDB
クラスは、特定のプロジェクトコンテキストで電子メールを送信するためのサポートを提供するためにサブクラス化されています。
from model.email import CampaignDB
class Campaign(CampaignDB):
"""
Provides sending capability to the email campaign ORM class.
"""
def __init__(self, audience_id=None, active=None, name=None):
self.audience_id = audience_id
self.active = active
self.name = name
def send(self):
print("send emails to the audience")
今私はSQLAlchemyののクラス継承階層を使用して多型拠点であることをCampaignDB
とサブクラス化Campaign
クラスをリファクタリングしたいと思います。たとえば、EmailCampaignDB
とPushCampaignDB
の基本クラスをCampaignDB
にしたいとします。次に、インポートプロジェクトでEmailCampaignDB
とPushCampaignDB
を別々に、EmailCampaign
とPushCampaign
のように拡張したいと思います。しかし、私はまだCampaign
を照会でき、EmailCampaign
とPushCampaign
のインスタンスが返されます。
私はこれを解決するためにいくつかの試みを行いましたが、問題が発生しました。特に、session.query(Campaign).all()
は、SQLAlchemyがそれを基本クラスと見なさないため、結果を返しません。生成されたSQLには、次のWHERE句があります。WHERE email.campaigns.type IN (NULL)
これは私が試みていることの要点です。
class CampaignDB(Base):
"""
Note: this basic database mapper class is expected to be extended.
When sub-classing, be mindful to override mappings to other extended classes.
"""
__tablename__ = 'campaigns'
audience_id = Column(Integer, ForeignKey("audiences.id"))
active = Column(Boolean)
name = Column(Text)
type = Column(String(16))
__mapper_args__ = {
'polymorphic_on': type
}
class EmailCampaignDB(CampaignBaseDB):
__mapper_args__ = {
'polymorphic_identity': 'email'
}
class PushCampaignDB(CampaignBaseDB):
__mapper_args__ = {
'polymorphic_identity': 'push'
}
def send(self):
print("send push notifications to the audience")
class Campaign(CampaignDB):
pass
class EmailCampaign(EmailCampaignDB):
def send(self):
print("send emails to the audience")
class PushCampaign(PushCampaignDB):
def send(self):
print("send push notifications to the audience")
これは可能ですか?この「パッケージ化されたORM」コンテキストでこれを達成するためのより良い方法はありますか?
[この質問](https://stackoverflow.com/questions/37621423)はあなたの正確な使用例です。 – univerio