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

时间:2014-10-06 12:46:34

标签: 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)

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

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()

我有一个例外: NoReferencedTableError:与列'users_to_roles.user_id'关联的外键无法找到用于生成用于定位列'id'的外键的表'用户'

我也尝试过以下方式:

@app.before_first_request
def initialize_database():
    db.create_all()

没有成功

我尝试将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'))

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

1 个答案:

答案 0 :(得分:4)

Flask-SQLAlchemy的一个功能是,在没有为模型类定义__tablename__类属性时,从类名生成自动表名。来自https://pythonhosted.org/Flask-SQLAlchemy/models.html

  

SQLAlchemy中需要的某些部分是可选的   烧瓶SQLAlchemy的。例如,表名是自动设置的   你除非被覆盖。它是从转换为的类名派生的   小写并将“CamelCase”转换为“camel_case”。

在您的情况下,User类会将其__tablename__属性推断为user,这意味着没有定义users表。

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

class User(db.Model, UserMixin):
    __tablename__ = 'users'
    ...

class Role(db.Model):
    __tablename__ = 'roles'
    ...

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

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