user7269028
user7269028

Reputation:

Why do I keep getting 'ImportError: cannot import name db'?

I am following this tutorial: getting started with flask-login.

However I am stuck at step 5 where I start to use SQLAlchemy. I believe the problem might be circular importing, based on what I have read but I'm still a little new to Python coding. This web app is a little project I am doing in my free time.

So I guess my overall question is, is this circular importing, and if not does anyone see what I might be doing wrong here? I am also running this using virtualenv using Python 2.7.

File Structure:

-noteapp
  -noteapp
    -db
    -forms
    -static
    -templates
    -views
  __init__.py 
  app.py
  models.py

This is my app.py file

from flask import Flask
from flask_login import LoginManager
from noteapp.models import db

from noteapp.views.index import bp as index_bp
from noteapp.views.createnote import bp as createnote_bp
from noteapp.views.signup import bp as signup_bp

def init_db():
    db.init_app(app)
    db.app = app
    db.create_all()

app = Flask(__name__)

app.secret_key = 'removed for reasons'
app.config['SQLALCHEMY_DATABASE_URI'] = 'removed for reasons'
db = SQLAlchemy(app)

login_manager = LoginManager(app)
login_manager.init_app(app)

app.register_blueprint(index_bp)
app.register_blueprint(createnote_bp)
app.register_blueprint(signup_bp)

if __name__ == '__main__':
    app.init_db()
    app.run(debug=True)

This is my models.py file:

from noteapp.app import app
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy(app)

class User(db.Model):
    email = db.Column(db.String(80), primary_key=True, unique=True)
    password = db.Column(db.String(80))
    def __init__(self, email, password):
        self.email = email
        self.password = password
    def __repr__(self):
        return '<User %r>' % self.email

Upvotes: 3

Views: 12922

Answers (1)

Urban48
Urban48

Reputation: 1476

You are correct you have a circle import issue.

At app.py you import from noteapp.models import db,
and at models.py you import from noteapp.app import app

A quick fix could be: at models.py use db = SQLAlchemy() without the app.
At the app.py module, import db from models.py and do db.init_app(app)

also remove db = SQLAlchemy(app) from your app.py

your app.py should look like this..

from noteapp.models import db
...
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'removed for reasons'
...
def init_db():
    db.init_app(app)
    db.app = app
    db.create_all()
...
if __name__ == '__main__':
    app.init_db()
    app.run(debug=True)

models.py should look like this:

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class User(db.Model):
    email = db.Column(db.String(80), primary_key=True, unique=True)
    password = db.Column(db.String(80))
    def __init__(self, email, password):
        self.email = email
        self.password = password
    def __repr__(self):
        return '<User %r>' % self.email

Upvotes: 11

Related Questions