Reputation: 10008
I have following application structure:
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)
When I trying to create initial DB structure following way:
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()
I've got an exception: NoReferencedTableError: Foreign key associated with column 'users_to_roles.user_id' could not find table 'users' with which to generate a foreign key to target column 'id'
I also tried to dow it following way:
@app.before_first_request
def initialize_database():
db.create_all()
with no success
I tried to move Role
to the same file where User
model is declared with the same result. I read the docs here: https://pythonhosted.org/Flask-SQLAlchemy/quickstart.html but it says 'you just need to import db
' and it does not works.
Here is how User
model and relationship table are declared (Role model looks similar to 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'))
How to create initial DB structure using Flask-SQLAlchemy?
Upvotes: 3
Views: 1214
Reputation: 2748
One of the features of Flask-SQLAlchemy
is automatic table name generation from the class name when the __tablename__
class attribute isn't defined for a model class. From https://pythonhosted.org/Flask-SQLAlchemy/models.html:
Some parts that are required in SQLAlchemy are optional in Flask-SQLAlchemy. For instance the table name is automatically set for you unless overridden. It’s derived from the class name converted to lowercase and with “CamelCase” converted to “camel_case”.
In your case, the User
class will have it's __tablename__
attribute inferred as user
which means there is no users
table defined.
You can fix this by either explicitly setting __tablename__
or by changing the ForeignKey
parameters to match the autogenerated table names:
class User(db.Model, UserMixin):
__tablename__ = 'users'
...
class Role(db.Model):
__tablename__ = 'roles'
...
or leave the __tablename__
attribute undefined and modify the association table:
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')))
Upvotes: 5