Flask-SQLAlchemy + create_all() 在创建多对多关系时失败

Ale*_*.P. 3 flask flask-sqlalchemy

我有以下应用程序结构:

run.py
|->app
   |->models
      |-> user.py (declares role-to-user relationship table and User model)
      |-> role.py (declares Role model)
   |-> main.py (contains initialization and all required imports)
   |-> extensions (here sqlalchemy variable declared to be imported later)
Run Code Online (Sandbox Code Playgroud)

当我尝试以下方式创建初始数据库结构时:

from app.models import *
from app.extensions import db
from app.main import myapp #app is initialized with all packages  like assets, db, security, etc.

with myapp.test_request_context():
    db.create_all()
Run Code Online (Sandbox Code Playgroud)

我有一个例外:NoReferencedTableError:与列“users_to_roles.user_id”关联的外键找不到用于生成目标列“id”的外键的表“users”

我也尝试按照以下方式进行操作:

@app.before_first_request
def initialize_database():
    db.create_all()
Run Code Online (Sandbox Code Playgroud)

没有成功

我尝试移动Role到声明模型的同一文件,User并得到相同的结果。我在这里阅读了文档: https: //pythonhosted.org/Flask-SQLAlchemy/quickstart.html但它说“你只需要导入db”并且它不起作用。

以下是User模型和关系表的声明方式(角色模型看起来类似于User):

users_to_roles_association_table = db.Table('users_to_roles',
    db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
    db.Column('role_id', db.Integer, db.ForeignKey('roles.id')))

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(255), unique=True)
    .......
    roles = db.relationship('Role', secondary=users_to_roles_association_table,
                            backref=db.backref('users', lazy='dynamic'))
Run Code Online (Sandbox Code Playgroud)

如何使用 Flask-SQLAlchemy 创建初始数据库结构?

dgi*_*and 5

\n\n

其功能之一是当未为模型类定义Flask-SQLAlchemy类属性时,自动从类名称生成表名称。__tablename__来自https://pythonhosted.org/Flask-SQLAlchemy/models.html

\n\n
\n

SQLAlchemy 中必需的某些部分在 Flask-SQLAlchemy 中是可选的。例如,除非被覆盖,否则会自动为您设置表名称。它\xe2\x80\x99s源自转换为\n小写的类名,并将\xe2\x80\x9cCamelCase\xe2\x80\x9d转换为\xe2\x80\x9ccamel_case\xe2\x80\x9d。

\n
\n\n

在您的情况下,该类将推断User其属性,这意味着没有定义表。__tablename__userusers

\n\n

您可以通过显式设置__tablename__或更改ForeignKey参数以匹配自动生成的表名称来解决此问题:

\n\n
class User(db.Model, UserMixin):\n    __tablename__ = \'users\'\n    ...\n\nclass Role(db.Model):\n    __tablename__ = \'roles\'\n    ...\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者保留__tablename__属性未定义并修改关联表:

\n\n
users_to_roles_association_table = db.Table(\'users_to_roles\',\n    db.Column(\'user_id\', db.Integer, db.ForeignKey(\'user.id\')),\n    db.Column(\'role_id\', db.Integer, db.ForeignKey(\'role.id\')))\n
Run Code Online (Sandbox Code Playgroud)\n