当我插入新记录时,我在理解ForeignKey约束如何与SqlAlchemy一起工作时遇到问题。我有一个包含两个子表的父表,每个子表都是one_2_many关系。我的底层数据库是Oracle,这是我的表的简化模型:
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()代码时引发异常。我不确定为什么要提出异常,我上面所做的似乎是我在各种在线帖子中看到的模式。有趣的是,如果我注释掉添加打印机子代的代码,这样可以正常工作。我非常困惑......:)
非常感谢任何帮助,指示或建议!
提前致谢, 道格
答案 0 :(得分:3)
product_category_id
上的外键Printer
引用'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()
与您的示例略有不同,因为当您将示例添加到问题中时,您遗漏了一些右括号,我略微更改了Printers
和Products
的示例。