繁体   English   中英

Flask SQLAlchemy:多对多关系错误

[英]Flask SQLAlchemy: many to many relationship error

我正在尝试在 SQLAlchemy 中建立多对多关系,但出现错误:

from shopapp import db
db.create_all()

sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'shoppinglists_products.shoppinglist_id_v2' could not find table 'shoppinglist' with which to generate a foreign key to target column 'id'

我的代码:

from sqlalchemy import ForeignKey
from shopapp import db


shoppinglists_products = db.Table("shoppinglists_products",
                                  db.Column("shoppinglist_id", db.Integer, ForeignKey("shoppinglist.id")),
                                  db.Column("product_id", db.Integer, ForeignKey("product.id")))

class ShoppingList(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20), unique=True, nullable=False)
    products = db.relationship('Product', back_populates="shoppinglists", secondary="shoppinglists_products")


class Product(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20), unique=True, nullable=False)

问题出在哪里?

似乎 Flask-SQLAlchemy 在查找外键引用表时遇到问题。 根据您的代码,您可以通过以下两种方法解决此问题:

1) 修复shoppinglists_products表:

Flask-SQLAlchemy 经常将CamelCased模型名称转换成类似于这样的语法: camel_cased 在您的情况下, ShoppingList将被称为shopping_list 因此,将ForeignKey("shoppinglist.id")更改为ForeignKey("shopping_list.id")就可以了。

shoppinglists_products = db.Table("shoppinglists_products",
             db.Column("shoppinglist_id", db.Integer, ForeignKey("shopping_list.id")), # <-- fixed
                                  

2)更改模型名称:

如果您愿意,您可以继续将模型名称从ShoppingList更改为Shopping ,稍后将其称为shopping 这将防止任何混淆进一步渲染。 通常,开发人员不会经常使用由两个单词组合而成的类名,尤其是对于 ORM 案例。 这是因为各种框架有不同的方式来解释类名来创建表。

扩展@P0intMaN 的答案 - 显式提供带有 __tablename__ = "ShoppingList" 的 SQL Alchemy 表名(例如)让您可以使用您喜欢的案例样式,并防止 SQLAlchemy 通过更改某种重要的名称而不告诉您来“帮助”您.

class ShoppingList(db.Model):
    __tablename__ = "ShoppingList"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20), unique=True, nullable=False)
    products = db.relationship('Product', back_populates="shoppinglists", secondary="shoppinglists_products")

在许多/大多数 Flask 教程和书籍中,使用了简单的表名(例如帖子、评论、用户),从而避免了这个问题。 因此,对于我们这些坚持有意义的 CamelCased 类名的人来说,一个陷阱等待着我们。 此处的文档中有些随意地提到了这一点: https ://flask-sqlalchemy.palletsprojects.com/en/2.x/models/

SQLAlchemy 中需要的一些部分在 Flask-SQLAlchemy 中是可选的。 例如,除非被覆盖,否则会自动为您设置表名。 它派生自转换为小写的类名,并将“CamelCase”转换为“camel_case”。 要覆盖表名,请设置tablename类属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM