我一直在绞尽脑汁,似乎无法解决如何解决这个问题。请注意,我已从模型中删除了大量不相关的字段
我正在编写我的SQL-Alchemy模型,并遇到了以下问题:
由于多个计费系统,每个都具有完全不同的属性,并且由于订阅属性的不同类型(即用户名,节点位置等),我不得不走多态继承之路。
class Subscription(Base):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255))
secret = db.Column(postgresql.BYTEA)
type = db.Column(SubscriptionType.db_type())
status = db.Column(StatusType.db_type())
subscription_id = db.Column(db.Integer)
__tablename__ = 'subscription'
__table_args__ = {'schema':'public'}
__mapper_args__ = {'polymorphic_on' : type}
def __repr__(self):
return '<Subscription: %r>' % self.id
class Product1(Subscription):
__mapper_args__ = {'polymorphic_identity' : SubscriptionType.product1}
id = db.Column(db.Integer, db.ForeignKey('public.subscription.id'),
primary_key = True)
billing_system = db.Column(
db.Integer,
db.ForeignKey('public.billing_system.id')
)
class BillingSystem(Base):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255))
type = db.Column(BillingSystemType.db_type())
__tablename__ = 'billing_system'
__table_args__ = {'schema':'public'}
__mapper_args__ = {'polymorphic_on' : type}
def __repr__(self):
return '<Subscription: %r>' % self.id
class BillingSystem1(BillingSystem):
__mapper_args__ = {'polymorphic_identity' : BillingSystemType.billingsystem1}
id = db.Column(db.Integer, db.ForeignKey('public.billing_system.id'),
primary_key = True)
billing_system = db.Column(
db.Integer,
db.ForeignKey('public.billing_system.id')
)
foo = db.Column(db.Integer)
bar = db.Column(db.Integer)
class BillingSystem2(BillingSystem):
__mapper_args__ = {'polymorphic_identity' : BillingSystemType.billingsystem2}
id = db.Column(db.Integer, db.ForeignKey('public.billing_system.id'),
primary_key = True)
billing_system = db.Column(
db.Integer,
db.ForeignKey('public.billing_system.id')
)
bing = db.Column(db.Integer)
boo = db.Column(db.Integer)
__tablename__ = 'billing_system_product2'
__table_args__ = {'schema':'public'}
除了一件事之外,一切正常。
说我运行以下内容:
>>> a = Product1()
>>> b = BillingSystem.objects.get(1)
>>> a.billing_system = b
>>> session.add(a)
>>> session.commit()
我会收到以下错误。
sqlalchemy.exc.ProgrammingError: (ProgrammingError) can't adapt type 'BillingSystem1' 'INSERT INTO
我理解它的含义,并尝试了以下内容。
>>> a.billing_system = b.id
这只存储ID,当我尝试检索关联的对象时,我会收到一个整数。这涉及到我不得不做一个额外的查询。我希望这不是可行的方法。
我还尝试将所有结算系统ID的外键添加到Product1 Model
class BillingSystem1(BillingSystem):
__mapper_args__ = {'polymorphic_identity' : BillingSystemType.billingsystem1}
id = db.Column(db.Integer, db.ForeignKey('public.billing_system.id'),
primary_key = True)
billing_system = db.Column(
db.Integer,
db.ForeignKey('public.billing_system.id'),
db.ForeignKey('public.billing_system1.id'),
db.ForeignKey('public.billing_system2.id'),
)
foo = db.Column(db.Integer)
bar = db.Column(db.Integer)
这根本不起作用,我收到了相同的ProgrammingError异常,说明该类型无法适应。
我已经搜索了手册,但找不到怎么做,但是我需要某种形式的魔法选项来实现这一点:
>>> a = BillingSystem.query.get(1)
>>> type(a)
BillingSystem
而不是:
>>> a = BillingSystem.query.get(1)
>>> type(a)
BillingSystem1
是否有人能够了解如何查询我的多态模型集以获取ID,并且只获得基本模型的类?
我觉得这会解决我的问题,我只是不确定如何解决它。
感谢您花时间阅读本文,我真的想知道我哪里出错了(我已经醒了太长时间,所以这没有帮助)。
干杯, 里斯
答案 0 :(得分:1)
class Subscription(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255))
secret = db.Column(postgresql.BYTEA)
type = db.Column(SubscriptionType.db_type())
status = db.Column(StatusType.db_type())
subscription_id = db.Column(db.Integer)
billing_system_id = db.Column(
db.Integer,
db.ForeignKey('public.billing_system.id')
)
billing_system = db.relationship('BillingSystem', backref='subscriptions')
所以我所做的是:
1)将Subscription.billing_system_id外键移至基本订阅模型 2)在Subscription.billing_system关系中添加
所以现在我这样做:
>>> o = BillingSystem.query.get(1)
>>> a = Product1()
>>> a.billing_system_id = o.id
结果是:
>>> a.billing_system.subscriptions
[<cPanel Hosting Reseller: 2>]
>>> a.billing_system_id
2
所以除非我在这里做错了,否则它似乎有效。我只是无法传递实际的BillingSystem对象,实际上我必须设置ID。虽然保存了模型,但仍然可以通过参考来强制执行,因此我没有看到太多问题。
感谢您的帮助:)