Inheritance + foreign keys

I am completely mistaken about this and cannot figure out how to get around this problem. Please note that many unnecessary fields are cut from my models.

I am in the middle of coding my SQL-Alchemy models and have encountered the following problem:

Due to several billing systems, each of which has completely different attributes, and because of different types of subscription attributes (for example, usernames, node, etc.), I had to go down the polymorphic inheritance path.

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'}

Everything is working fine, except for one.

Let's say that I run the following:

>>> a = Product1()
>>> b = BillingSystem.objects.get(1)
>>> a.billing_system = b
>>> session.add(a)
>>> session.commit()

I get the following error.

sqlalchemy.exc.ProgrammingError: (ProgrammingError) can't adapt type 'BillingSystem1' 'INSERT INTO

I understand what he is saying, and I tried the following.

>>> a.billing_system = b.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 ?

, , , .

, , , , ( , ).

Cheers,

+5
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 Relationship

, :

>>> 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. - , , .

:)

+1

All Articles