1

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'

1 Answer 1

5

This is a regular case of cyclic imports conflict. The traceback gives you a clear steps:

How it goes in steps:

  • you run main.py
  • the control flow starts importing features/libraries till it gets the 3rd line from databases import User.
  • it goes to the 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)
  • from the position of previous step being at database.py the control flow encounters from main import db - that means it should turn back to the main(main.py) module!
  • control flow returned to the 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)
    • and you run into cycle ...

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

    • ---> then custom DB models created (like User(db.Model)) depending on db instance

main.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)  

Sign up to request clarification or add additional context in comments.

8 Comments

How to make it create a table in the db by using the User class in the databases.py file??
@PaulSteven, see the update. Use models after instantiating db
Now the class was imported successfuly. Eventhough the table was not created yet.
@PaulSteven, add db.session.commit() after db.create_all()
no table created even after adding db.session.commit() after db.create_all(). It creates a file only.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.