SQLAlchemy多对多加入

时间:2017-02-25 17:46:58

标签: python join flask sqlalchemy many-to-many

这是我的模型:产品和标签具有多对多关系

products_tags_table=db.Table('products_tags',
                        db.Column('product_id', db.Integer,db.ForeignKey('products.id'), nullable=False),
                        db.Column('tag_id',db.Integer,db.ForeignKey('tag.id'),nullable=False),
                        db.PrimaryKeyConstraint('product_id', 'tag_id')
                        )

class Tag(db.Model):
    __tablename__ = "tags"
    id = db.Column( db.Integer, primary_key = True)
    name = db.Column( db.String(256) )
    description = db.Column( db.Text() )
    background_img_url = db.Column( db.String(256) )
    products =db.relationship('Product',
                              secondary=products_tags_table,
                              backref='product_tags'
                             )  




class Product(db.Model):
    __tablename__ = "products"
    id = db.Column( db.Integer, primary_key = True)
    name = db.Column( db.String(256) )
    tags=db.relationship('ProductTag',
                        secondary=products_tags_table,
                        backref='tag_products'
                        )  

当我使用Product加入Tag时。我收到了错误:

class' sqlalchemy.exc.InvalidRequestError':无法找到要加入的FROM子句。尝试加入,但得到:在' product_tags'之间找不到任何外键关系。和'产品'。

以下是我的加入代码:

avai_tags = Tag.query.join(Product).order_by(ProductTag.name)

我错过了什么吗?

1 个答案:

答案 0 :(得分:5)

首先,在您的产品表中,您的第二个外键需要属性引用表名"标记",所以更改' tag.id'到' tags.id'

products_tags_table=db.Table('products_tags',
                    db.Column('product_id', db.Integer,db.ForeignKey('products.id'), nullable=False),
                    db.Column('tag_id',db.Integer,db.ForeignKey('tags.id'),nullable=False), 
                                                                   #^Missing 's'
                    db.PrimaryKeyConstraint('product_id', 'tag_id')
                    )

然后在您的产品模型中,您希望准确地引用相应模型的名称。改变' ProductTag'到'标记'

tags=db.relationship('Tag', # 'ProductTag' <- This is a relationship to the Tag table.
                    secondary=products_tags_table,
                    backref='tag_products'
                    )  

然后尝试这样的加入

query = Tag.query.join(Product, Tag.products)

avail_tags = query.order_by(Tag.name).all()