Reputation: 41
I am writing a flask application. I have two files. main.py and databases.py. I want to create a database from the database.py file. The main.py should access the databases.py file and create the database and table named "Users". But it shows import error. Help me with this issue
main.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from databases import User
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/data_log.db'
db = SQLAlchemy(app)
if __name__ == '__main__':
db.create_all()
app.run(host='0.0.0.0', port=5001)
databases.py
from main import db
from passlib.apps import custom_app_context as pwd_context
class User(db.Model) :
__tablename__ = 'users'
user_id = db.Column(db.Integer, primary_key = True)
username = db.Column(db.String(32), index = True)
password = db.Column(db.String(128))
def hash_password(self, password) :
self.password =pwd_context.hash(password)
def verify_password(self, password) :
return pwd_context.verify(password, self.password)
Traceback:
Traceback (most recent call last):
File "main.py", line 3, in <module>
from databases import User
File "/home/paulsteven/stack/databases.py", line 1, in <module>
from main import db
File "/home/paulsteven/stack/main.py", line 3, in <module>
from databases import User
ImportError: cannot import name 'User'
Upvotes: 1
Views: 3465
Reputation: 92854
This is a regular case of cyclic imports conflict. The traceback gives you a clear steps:
How it goes in steps:
main.py
from databases import User
.databases
module to find the needed User
class. But ... the User
may use the outer scope features (and it does require db.Model
), so the control flow needs to scan databases
module from the start. This reflects the 2nd step from traceback ("/home/paulsteven/stack/databases.py", line 1
)database.py
the control flow encounters from main import db
- that means it should turn back to the main
(main.py
) module!main
module start scanning again from the 1st line - till it finds from databases import User
again. This reflects the traceback's 3rd step (File "/home/paulsteven/stack/main.py", line 3
)
What is right way to solve the issue?
Keep all DB context/DB models in separate module(s).
Follow the sequence of objects relations and how they depend on each other:
---> Application instantiated first (app
)
---> then DB framework instance is created db = SQLAlchemy(app)
depending on app
User(db.Model)
) depending on db
instancemain.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
# from databases import User <--- shouldn't be here
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/data_log.db'
db = SQLAlchemy(app)
if __name__ == '__main__':
from databases import User # after instantiating `db` import model(s)
db.create_all()
app.run(host='0.0.0.0', port=5001)
Upvotes: 5