![](/img/trans.png)
[英]Flask + sqlalchemy + marshmallow - Error on relationship - One to Many
[英]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.