2012-06-05 22 views
5

Beynimi kesinlikle bunun üzerine taşıyordum ve bu sorunun nasıl üstesinden geleceğimi düşünmüyorum. Benim modellerin dışında alakasız alanların sürü kestik unutmayınızKalıtım + Yabancı Anahtarlar

benim SQL Simya modellerini kodlama ortasında benim ve aşağıdaki sorunu karşılaştı:

nedeniyle birden fazla faturalandırma sistemleri, her tamamen farklı özelliklere sahip olan ve farklı Abonelik özellikleri (örneğin, kullanıcı adları, düğüm konumları vb.) nedeniyle, polimorfik miras yoluna gitmem gerekti.

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

Her şey bir şey hariç, her şey yolunda.

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

aşağıdaki hatayı alırsınız:

Aşağıdaki çalıştırmak varsayalım.

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

Ne söylediğini anlıyorum ve aşağıdakileri denedim.

>>> a.billing_system = b.id 

Bu depolayan İD, ve ilişkili nesnesi retreive çalışırken, bunun yerine bir tamsayı alır. Bu, ek bir sorgu yapmak zorunda kalmamı gerektiriyor. Bunun böyle bir yol olmadığını umuyorum.

Ben de bu da hiç işe yaramadı Ürün1 Modeli

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) 

için faturalandırma sistemi kimlikleri tümü için yabancı anahtarları ekleyerek denedim ve ben belirten aynı ProgrammingError durum aldı tip can olduğunu uyum gösterme.

Ben kılavuzu trawled gelmiş ve bunu nasıl bulamıyor, ama bunun için izin büyülü seçenek çeşit gerekir:

>>> a = BillingSystem.query.get(1) 
>>> type(a) 
BillingSystem 

yerine:

>>> a = BillingSystem.query.get(1) 
>>> type(a) 
BillingSystem1 

Herhangi biri, bir Kimlik için Polimorfik modeller kümemi nasıl sorgulayabildiğime ve yalnızca temel model sınıfını nasıl elde edebileceğime dair herhangi bir ışık tutabilir mi?

Bunun benim problemimi çözeceğini hissediyorum, sadece nasıl çalıştığını bilmiyorum.

Bunu okumak için zaman ayırdığınız için teşekkür ederim ve nerede yanlış gittiğimi öğrenmek isterim (çok uzun zamandır uyanık kaldım, bu yüzden işe yaramıyor).

Alkış, Rhys

+3

için

sayesinde bu muhtemelen sizin için bir süper-yararlı cevap olacak değil, ancak ben size yardımcı olabilir olmadığını öğrenmek için, bir okumak zorunda olacak gibi görünüyor Kodunuzun büyük miktarda ve küçük ayrıntıları anlamaya. Bu sitedeki bir yanıtı almanın en iyi yolu, kodu inanılmaz derecede basit olana kadar bozmaya çalışmaktır, ancak yine de aynı hatayı verir. Sonra çok özel bir soru sorabilirsin: "Neden bu 4 satır kodun 3. satırı hata veriyor?" Ek bir bonus olarak, aslında bu işlemi yaparken aslında * sorunu çözersiniz. İyi şanslar! –

+1

Bazı dinlenme ve tavsiyeleriniz çok yardımcı oldu! Teşekkür ederim :) –

cevap

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

Yani ne yapmış olduğunu:

1) Abonelik eklendi Baz Abonelik Modeli 2) için Subscription.billing_system_id yabancı anahtarı yukarı Shifted.billing_system İlişki

yüzden şimdi yapıyorum: sonuçlanır

>>> o = BillingSystem.query.get(1) 
>>> a = Product1() 
>>> a.billing_system_id = o.id 

: Burada yanlış bir şey yapıyorum sürece

>>> a.billing_system.subscriptions 
[<cPanel Hosting Reseller: 2>] 
>>> a.billing_system_id 
2 

Yani, iş gibi görünüyor. Sadece gerçek BillingSystem nesnesini geçemiyorum, aslında kimliği ayarlamalıyım. Yine de, model kaydedildiği zaman referansla uygulanmaktadır, bu yüzden çok fazla sorun görmüyorum. Yardımlarınız :)

İlgili konular