2

I'm trying to import database and get an error "cannot import name 'db'". I've seen answers on such problem, but none of them helped in my case. Tree of my project:

chat
  | chat.py
  └─ app
      │   models.py
      │   __init__.py
      │
      ├─── main
      │      events.py
      │      forms.py
      │      routes.py
      │      __init__.py

chat.py:

from app import create_app, socketio

app = create_app(debug=True)

if __name__ == '__main__':
    socketio.run(app)

app\init.py:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_socketio import SocketIO

socketio = SocketIO()

def create_app(debug=False):
    app = Flask(__name__)
    app.debug = debug
    app.config['SECRET_KEY'] = 'gjr39dkjn344_!67#'
    app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql:///site.db'
    db = SQLAlchemy(app)
    from .main import main as main_blueprint
    app.register_blueprint(main_blueprint)
    socketio.init_app(app)
    return app 

app\main\init.py:

from flask import Blueprint

main = Blueprint('main', __name__)

from . import routes, events 

app\models.py:

from app import db

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(15), nullable=False)
    session_id = db.Column(db.String(200), nullable=False)
    isready = db.Column(db.Boolean, default='False')
    room = db.relationship('Room', backref='spy')
    def __repr__(self):
        return f"User('{self.username}')"

So, when I'm trying from app import db in python terminal I get

ImportError: cannot import name 'db'

Since I'm new to flask (and web at all), I have no idea, what to do. I've tried this solution (kinda closest to my case) and all alike answers but it didn't work. What can I try?

1 Answers1

1

db is just a local variable in the create_app() function. You'll need to create that object outside of the create_app() factory.

You can create the Flask-SQLAlchemy db plugin object without passing in an app argument, and in the factory connect that object to te Flask app with the .init_app() method, just like you already do for the Flask-SocketIO plugin:

db = SQLAlchemy()

def create_app(debug=False):
    app = Flask(__name__)
    app.debug = debug
    app.config['SECRET_KEY'] = 'gjr39dkjn344_!67#'
    app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql:///site.db'

    db.init_app(app)
    socketio.init_app(app)

    from .main import main as main_blueprint
    app.register_blueprint(main_blueprint)

    return app 

Now db is available as a global in the module, and so can be imported elsewhere.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Well, I got another problem. "No application found. Either work inside a view function or push" when I try to db.create_app(). So I did it using "with app.app_context()" as it recommended in documentation, but now I can't import classes. I get "ImportError: cannot import name 'User'" – elephantsdadshusband Jan 16 '19 at 05:18
  • @elephantsdadshusband: those are new, independent issues. You could post those as new questions. – Martijn Pieters Jan 16 '19 at 11:37
  • @elephantsdadshusband: put differently: I can't solve those problems *here*, I don't have enough information nor should this question be altered to add those details. *This* specific problem has been solved, and is useful for future visitors with the same problem (which is what SO is all about). – Martijn Pieters Jan 16 '19 at 11:44