[英]SqlAlchemy foreign key constraint
I'm having a problem understanding how a ForeignKey constraint works with SqlAlchemy when I'm inserting new records. 在插入新记录时,我在理解ForeignKey约束与SqlAlchemy一起工作时遇到问题。 I've got a parent table that has two child tables, each is a one_2_many relationship.
我有一个具有两个子表的父表,每个子表是一个one_2_many关系。 My underlying DB is Oracle, and here's a simplified model of my tables:
我的基础数据库是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)
And here's a simplified example of the Python code that's raising a (cx_Oracle.IntegrityError) ORA-02291: integrity constraint (EASTLAB.SYS_C0049050) violated - parent key not found exception 这是引发(cx_Oracle.IntegrityError)ORA-02291的Python代码的简化示例:违反了完整性约束(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()
The exception is raised at the point where the db.session.commit() code is executed. 在执行db.session.commit()代码时会引发异常。 I'm not sure why the exception is being raised, what I'm doing above seems to be a pattern I've seen in various online postings.
我不确定为什么会引发异常,我在上面所做的事情似乎是我在各种在线帖子中看到的模式。 The interesting thing is if I comment out the code that adds the printer children, this works fine.
有趣的是,如果我注释掉添加打印机子代的代码,则可以正常工作。 I'm very confused... :)
我很困惑... :)
Any help, pointers or suggestions would be greatly appreciated! 任何帮助,指示或建议将不胜感激!
Thanks in advance, Doug 预先感谢,道格
The foreign key product_category_id
on Printer
is referencing 'product_category.product_category_id'
and not 'productcategory.product_category_id'
. Printer
上的外键product_category_id
引用'product_category.product_category_id'
是'product_category.product_category_id'
而不是'productcategory.product_category_id'
。
Tested this with the below which works for me: 用下面的方法对我进行了测试:
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()
Slightly different from your example as you left out some closing brackets when you added the example to your question and I slightly changed how it got the samples for Printers
and Products
. 与示例略有不同,在将示例添加到问题中时,您省略了一些右方括号,而我略微更改了其获取
Printers
和Products
示例的方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.