2017-09-23 208 views
0

我有一個問題,當我插入新記錄時瞭解ForeignKey約束如何與SqlAlchemy一起工作。我有一個有兩個子表的父表,每個表都是一個one_2_many關係。我根本DB是Oracle,這是我的表的簡化模型:SqlAlchemy外鍵約束

class ProductCategory(db.Model): 
    __tablename__ = 'productcategory' 
    product_category_id = Column(Integer, Sequence('productcategory_seq', primary_key=True) 
    label = Column(String) 
    products = relation('Product', backref='product_category') 
    printers = relation('Printer', backref='product_category') 

class Product(db.Model): 
    __tablename__ = 'product' 
    product_id = Column(Integer, Sequence('product_seq'), primary_key=True) 
    product_category_id = Column(Integer, ForeignKey('productcategory.product_category_id') 
    name = Column(String) 

class Printer(db.Model): 
    __tablename__ = 'printer' 
    printer_id = Column(Integer, Sequence('printer_seq'), 
    product_category_id = Column(Integer, ForeignKey('product_category.product_category_id') 
    name = Column(String) 

而這裏的Python代碼是一個人要養一(cx_Oracle.IntegrityError)ORA-02291的一個簡單的例子:完整性約束(EASTLAB.SYS_C0049050)違反 - 父鍵未找到異常

try: 
    product_category = ProductCategory(label='some_category') 
    db.session.add(product_category) 

    # iterate over the products in the category 
    for product in products: 
    new_product = Product(
     product_category=product_category, 
     name=product.name 
    ) 
    db.session.add(new_product) 

    # iterate over the printers in the category 
    for printer in printers: 
    new_printer = Printer(
     product_category=product_category, 
     name=printer.name 
    ) 
    db.session.add(new_printer) 

    # commit before exiting context manager 
    db.session.commit() 
except: 
    db.session.rollback() 

在db.session.commit()代碼執行的位置引發異常。我不確定爲什麼異常會被提出,我在上面做的事情似乎是我在各種在線帖子中看到的模式。有趣的是,如果我將添加打印機子代碼的代碼註釋掉,這可以正常工作。我很困惑...... :)

任何幫助,指針或建議將不勝感激!

由於提前, 道格

回答

2

Printer外鍵product_category_id被引用'product_category.product_category_id'而不是'productcategory.product_category_id'

測試了這個與下面這對我的作品:

class ProductCategory(Base): 
    __tablename__ = 'productcategory' 
    product_category_id = Column(Integer, Sequence('productcategory_seq'), primary_key=True) 
    label = Column(String) 
    products = relation('Product', backref='product_category') 
    printers = relation('Printer', backref='product_category') 


class Product(Base): 
    __tablename__ = 'product' 
    product_id = Column(Integer, Sequence('product_seq'), primary_key=True) 
    product_category_id = Column(Integer, ForeignKey('productcategory.product_category_id')) 
    name = Column(String) 


class Printer(Base): 
    __tablename__ = 'printer' 
    printer_id = Column(Integer, Sequence('printer_seq'), primary_key=True) 
    product_category_id = Column(Integer, ForeignKey('productcategory.product_category_id')) 
    name = Column(String) 


Base.metadata.create_all(engine) 

Session = sessionmaker(bind=engine) 
session = Session() 

product_category = ProductCategory(label='some_category') 
session.add(product_category) 

product_names = ["a", "b", "c"] 

# iterate over the products in the category 
for product in product_names: 
    new_product = Product(
     product_category=product_category, 
     name=product 
    ) 
    session.add(new_product) 

printer_names = ["a", "b", "c"] 

# iterate over the printers in the category 
for printer in printer_names: 
    new_printer = Printer(
     product_category=product_category, 
     name=printer 
    ) 
    session.add(new_printer) 

# commit before exiting context manager 
session.commit() 

從你的例子稍有不同,因爲你忽略了一些閉幕括號當你添加的例子,你的問題,我稍微改變了它是如何得到的樣品爲PrintersProducts