What is the correct way to solve this circular import error using a Flask drawing?

I had a problem with cyclic import, so I moved my drawing under my definition. However, I still have an import error.

Traceback (most recent call last): File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 2217, in <module> globals = debugger.run(setup['file'], None, None) File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 1643, in run pydev_imports.execfile(file, globals, locals) # execute the script File "/Users/benjamin/Documents/Projects/website/server/app/app.py", line 15, in <module> from views import site File "/Users/benjamin/Documents/Projects/website/server/app/views.py", line 2, in <module> from models import User File "/Users/benjamin/Documents/Projects/website/server/app/models.py", line 3, in <module> from database_setup import db File "/Users/benjamin/Documents/Projects/website/server/app/database_setup.py", line 1, in <module> from app import app File "/Users/benjamin/Documents/Projects/website/server/app/app.py", line 15, in <module> from views import site ImportError: cannot import name site 

If I transferred the import and registration of the drawing to if __name__ == '__main__': problem will disappear, but I'm not sure if this is a good idea.

 if __name__ == '__main__': from views import site app.register_blueprint(site) app.run() 

Is this the correct solution to the problem or is there another solution?


original app.py without __main__ "fix":

 from flask import Flask app = Flask(__name__) from views import site app.register_blueprint(site) if __name__ == '__main__': app.debug = True app.run() 

views.py :

 from flask import Blueprint, render_template site = Blueprint('site', __name__, template_folder='templates', static_folder='static') @site.route('/', methods=['GET', 'POST']) def index(): return render_template('index.html') 

database_setup.py :

 from app import app from flask_mongoengine import MongoEngine app.config['MONGODB_SETTINGS'] = {'db': 'mst_website'} db = MongoEngine(app) 

models.py :

 from database_setup import db class User(db.Document): # ... 

My file structure:

 /server |-- requirements.txt |-- env/ (virtual environment) |-- app/ (my main app folder) |-- static/ |-- templates/ |-- __init__.py |-- app.py |-- database_setup.py |-- models.py |-- views.py 
+6
source share
1 answer

You have circular imports in your code. Based on tracking:

  • app.py does from views import site
  • views.py does from models import User
  • models.py does from database_setup import db
  • database_setup.py does from app import app
  • app.py does from views import site

Based on this order of events, the app.py you posted is not what actually causes your problem. Right now, the app not been defined before views are imported, so when it is further down the chain, it will try to get the app , it is not yet available.

You need to restructure the project so that everything that depends on the app is imported after the app defined. From your question, it seems that you think you did, but perhaps there is still an import written above app that you missed.


Probably unrelated, but you are currently using "relative" imports that are discouraged. Instead of from views import site , etc. You must make an absolute path: from app.views import site or a relative path: from .views import site .


To answer the initial question β€œuses __main__ to import drawings, a good idea?”, It is not. The problem is that __main__ protection is only performed when the module is launched directly. When you go to deploy it using a real application server such as uWSGI or Gunicorn, none of your drawings will be imported or registered.

+2
source

Source: https://habr.com/ru/post/988859/


All Articles