![](/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.