2017-09-23 164 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