2015-06-10 11 views
6

Ho riscontrato un problema con un'importazione circolare, quindi ho spostato la mia importazione di cianografia sotto la definizione dell'app. Tuttavia, sto ancora avendo un errore di importazione.Qual è il modo corretto per risolvere questo errore di importazione circolare con un progetto Flask?

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 

Se sposto l'importazione progetto e la registrazione al if __name__ == '__main__':, il problema va via, ma non sono sicuro se questa è una buona idea.

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

È questo il modo giusto per risolvere il problema oppure esiste un'altra soluzione?


originale app.py senza __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): 
    # ... 

La mia struttura del file è:

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

Inserendo l'importazione e la chiamata a 'register_blueprint' all'interno di if, il progetto non verrà registrato se si esegue l'applicazione senza eseguire direttamente il file (ad es. Con uwsgi). – dirn

+0

@dirn Non è quello che ho fatto qui inserendo l'importazione all'interno di 'if __name__ == '__main __':'? – benjaminz

+0

Sta dicendo che mettendo cose in quella guardia, è solo in esecuzione se si esegue direttamente il file. Quando si utilizza un vero app server, ciò non accadrà, quindi tutti i progetti saranno "mancanti". – davidism

risposta

2

Hai un import circolare nel codice. Sulla base del traceback:

  1. app.py fa from views import site
  2. views.py fa from models import User
  3. models.py fa from database_setup import db
  4. database_setup.py fa from app import app
  5. app.py fa from views import site

In base a questo ordine di eventi, lo app.py che hai pubblicato non è quello che causa il tuo problema. Al momento, app non è stato definito prima dell'importazione dello views, quindi quando più in basso la catena tenta di ottenere app, non è ancora disponibile.

È necessario ristrutturare il progetto in modo che tutto quello che dipende da app viene importato dopoapp è definito. Dalla tua domanda, sembra che tu pensi di averlo fatto, ma forse c'è ancora un'importazione scritta sopra lo app che ti sei perso.


Probabilmente non collegati, ma che si sta utilizzando le importazioni "relativi", che sono scoraggiati. Anziché eseguire from views import site, ecc., È necessario eseguire un percorso assoluto: from app.views import site o un percorso relativo: from .views import site.


Per rispondere alla domanda iniziale di "sta usando __main__ importare progetti una buona idea?", Non lo è. Il problema è che la protezione __main__ è solo eseguita quando si esegue direttamente il modulo. Quando vai a distribuire questo utilizzando un vero server di app come uWSGI o Gunicorn, nessuno dei tuoi progetti verrà importato o registrato.

Problemi correlati