2012-06-05 38 views
5

Tôi đã hoàn toàn đánh cắp bộ não của mình về vấn đề này và dường như không thể tìm ra cách giải quyết vấn đề. Xin lưu ý rằng tôi đã cắt giảm rất nhiều các lĩnh vực không liên quan ra khỏi mô hình của tôiThừa kế + Phím nước ngoài

Tôi đang ở giữa mã hóa lên mô hình SQL-Alchemy của tôi, và đã gặp phải những vấn đề sau đây:

Do nhiều hệ thống thanh toán, mỗi với các thuộc tính hoàn toàn khác nhau và do các loại thuộc tính Đăng ký khác nhau (tức là tên người dùng, vị trí nút, v.v.), tôi đã phải đi xuống đường thừa kế đa hình.

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

Mọi thứ đều hoạt động tốt, ngoại trừ một điều.

Nói rằng tôi chạy như sau:

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

tôi sẽ nhận được lỗi sau.

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

Tôi hiểu điều gì đang nói và tôi đã thử những điều sau đây.

>>> a.billing_system = b.id 

Chỉ lưu ID và khi tôi cố gắng truy xuất đối tượng liên quan, thay vào đó tôi nhận được số nguyên. Điều này liên quan đến việc tôi phải thực hiện một truy vấn bổ sung. Tôi hy vọng rằng đây không phải là cách để đi.

Tôi cũng đã thử thêm phím nước ngoài cho tất cả các ID hệ thống thanh toán đến Product1 Mẫu

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) 

này cũng không làm việc ở tất cả, và tôi nhận được ngoại lệ ProgrammingError cùng nói rằng các loại có thể không thích ứng.

Tôi đã trawled hướng dẫn, và không thể tìm thấy làm thế nào để làm điều đó, nhưng tôi cần một số hình thức lựa chọn kỳ diệu để cho phép điều này xảy ra:

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

Thay vì:

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

Có ai có thể làm sáng tỏ cách tôi có thể truy vấn tập hợp các mô hình Đa hình của tôi cho một ID, và chỉ lấy được lớp của mô hình cơ sở không?

Tôi cảm thấy rằng điều này sẽ giải quyết được vấn đề của tôi, tôi không chắc chắn về cách giải quyết vấn đề.

Cảm ơn đã dành thời gian để đọc điều này, và tôi thực sự muốn tìm ra nơi tôi đang đi sai (tôi cũng đã thức tỉnh quá lâu, vì vậy mà không phải là giúp đỡ).

Chúc mừng, Rhys

+3

Điều này có lẽ sẽ không có một câu trả lời siêu hữu ích cho bạn, nhưng có vẻ như để tìm hiểu xem tôi có thể giúp bạn, tôi sẽ phải đọc một số lượng lớn mã của bạn và tìm ra các chi tiết nhỏ. Cách tốt nhất để nhận được câu trả lời trên trang này là cắt mã xuống cho đến khi nó vô cùng đơn giản nhưng vẫn cho cùng một lỗi. Sau đó, bạn có thể đặt một câu hỏi rất cụ thể: "tại sao dòng 3 trong số 4 dòng mã này lại bị lỗi?" Như là một tiền thưởng thêm bạn thường thực sự * giải quyết vấn đề * khi bạn đi qua quá trình này. Chúc may mắn! –

+1

Một số phần còn lại và lời khuyên của bạn đã giúp rất nhiều! Cảm ơn bạn :) –

Trả lời

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

Vì vậy, những gì tôi đã làm là:

1) Shifted Ngoại chính Subscription.billing_system_id lên đến cơ sở đăng ký mẫu 2) Thêm vào đăng ký.billing_system Mối quan hệ

Vì vậy, bây giờ tôi đang làm điều này:

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

mà kết quả trong:

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

Vì vậy, trừ khi tôi đang làm một cái gì đó sai ở đây, có vẻ như để làm việc. Tôi chỉ không thể vượt qua đối tượng BillingSystem thực tế, tôi thực sự phải đặt ID. Nó vẫn được thực thi bắt buộc khi mô hình được lưu mặc dù, vì vậy tôi không thấy quá nhiều vấn đề với nó.

Nhờ sự giúp đỡ của bạn :)

Các vấn đề liên quan