python - flask-sqlalchemy multiple relationship types between two tables -
i having trouble setting multiple relationships between 2 models. these 2 models have them now:
class product(db.model): tablename='product' id = db.column(db.integer, primary_key=true) name = db.column(db.string(50)) image_id = db.column(db.integer, db.foreignkey('image.id')) image = db.relationship('image',uselist=false,backref=db.backref('product')) class image(db.model): __tablename__='address' id = db.column(db.integer, primary_key=true) normal = db.column(db.string(200)) product_id = db.column(db.integer, db.foreignkey('product.id')) product = db.relationship('product', backref='product_images')
product should have one-to-one cover image, , 1 many gallery of other images. however, there circular dependency foreign keys.
i in 2 tables. there way implement these 2 relationships?
at point code above throws:
sqlalchemy.exc.ambiguousforeignkeyserror
there 2 circular dependencies here:
- the foreign keys mutually dependent on existence of each table. 1 of fks must created after dependent table exists. set
use_alter=true
,name='some_name
on 1 resolve this. - the relationships both need resolve primary_key of target after insert, mutually dependent on both having been commited. set
post_update=true
on 1 resolve this.
see following documentation:
here working example demonstrating solution.
from sqlalchemy import create_engine, column, integer, string, foreignkey, table sqlalchemy.ext.declarative import declarative_base sqlalchemy.orm import sessionmaker, relationship engine = create_engine('sqlite:///:memory:', echo=true) session = sessionmaker(bind=engine) session = session() base = declarative_base(bind=engine) class product(base): __tablename__ = 'product' id = column(integer, primary_key=true) name = column(string, nullable=false) # cover image foreign key # use_alter=true along name='' adds foreign key after image has been created avoid circular dependency cover_id = column(integer, foreignkey('image.id', use_alter=true, name='fk_product_cover_id')) # cover image one-to-one relationship # set post_update=true avoid circular dependency during cover = relationship('image', foreign_keys=cover_id, post_update=true) class image(base): __tablename__ = 'image' id = column(integer, primary_key=true) path = column(string, nullable=false) product_id = column(integer, foreignkey(product.id)) # product gallery many-to-one product = relationship(product, foreign_keys=product_id, backref='images') # nothing special need in image, circular dependencies solved in product base.metadata.create_all() # create images i1 = image(path='img1') i2 = image(path='img2') i3 = image(path='img3') i4 = image(path='img4') # create product images, 1 of cover p1 = product(name='sample', images=[i1, i2, i3, i4], cover=i2) session.add(p1) session.commit() print 'cover:', p1.cover.path # prints 1 cover image path print 'images:', [i.path in p1.images] # prints 4 gallery image paths print 'image product:', p1.images[0].product.name # prints product name image perspective
Comments
Post a Comment