2017-09-23 62 views
0

新しいレコードを挿入するときにForeignKey制約がSqlAlchemyとどのように機能するかを理解できない問題があります。私は2つの子テーブルを持つ親テーブルを持っている、それぞれone_2_many関係です。私の基本的なDBは、Oracleであり、ここでは私のテーブルの単純化したモデルです:整合性制約(EASTLAB.SYS_C0049050):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) 

そして、ここでは(cx_Oracle.IntegrityError)ORA-02291を上げていますPythonのコードの簡単な例です違反 - 親キーが見つかりません例外

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()コードが実行された時点で発生します。なぜ例外が発生しているのか分かりませんが、私が上でやっていることは、さまざまなオンライン投稿で見たパターンのようです。興味深いのは、プリンタの子を追加するコードをコメントアウトすると、これはうまく動作します。私は非常に混乱しています... :)

すべての助け、指針または提案は非常に高く評価されるでしょう!事前に

おかげで、Printerの外部キーproduct_category_id'product_category.product_category_id'なく'productcategory.product_category_id'を参照している ダグ

答えて

2

あなたの例とは若干異なる
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である。