Не удается импортировать объект монго в другой файл - PullRequest
0 голосов
/ 18 сентября 2018

Используя флеш-отдых, я не могу импортировать объект mongo = PyMongo() из файла app/__init__.py в app/common/db.py.

Моя структура папок выглядит следующим образом:

myproject/
   run.py
   app/
      __init__.py
      config.py
      common/
         __init__.py
         db.py
      auth/
         __init__.py
         resources.py

app / __ init __. Py содержит:

from flask import Flask, Blueprint
from flask_pymongo import PyMongo
from flask_restful import Api
from app.config import Config

from app.auth.resources import Foo

mongo = PyMongo()

bp_auth = Blueprint('auth', __name__)
api_auth = Api(bp_auth)

api_auth.add_resource(Foo, '/foo/<string:name>')

def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    mongo.init_app(app)

    app.register_blueprint(bp_auth)

    return app

app / common / db.py содержит:

from app import mongo

само приложение запускается из корня через run.py , которое содержит:

from app import create_app

app = create_app()

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

Проблема:

Запустив приложение, я получаю ошибку ImportError:

из приложения import mongo

ImportError: невозможно импортировать имя 'mongo'

Почему это не работает?

Спасибо за вашу помощь!

EDIT:

Полная трассировка:

    Traceback (most recent call last):
  File "run.py", line 1, in <module>
    from app import create_app
  File "/home/bt/Dropbox/dev/flask/test_api/app/__init__.py", line 13, in <module>
    from app.auth.resources import SignIn, Users, User, Foo
  File "/home/bt/Dropbox/dev/flask/test_api/app/auth/resources.py", line 8, in <module>
    from app.common.resources import AuthResource
  File "/home/bt/Dropbox/dev/flask/test_api/app/common/resources.py", line 3, in <module>
    from app.auth.decorators import token_required
  File "/home/bt/Dropbox/dev/flask/test_api/app/auth/decorators.py", line 6, in <module>
    from app.common.database import users
  File "/home/bt/Dropbox/dev/flask/test_api/app/common/database.py", line 1, in <module>
    from app import mongo
ImportError: cannot import name 'mongo'

1 Ответ

0 голосов
/ 18 сентября 2018

Как я и подозревал, это проблема кругового импорта .

Вы можете отслеживать замкнутый цикл зависимостей, просматривая трассировку:

app -> resources -> database -> app

Это распространенная ошибка, которая не документирована должным образом в руководствах по Flask. Как объясняет здесь Lepture , вам следует избегать декларирования db в __init__.py

Я всегда придерживаюсь этого правила при написании модулей и пакетов:

Не выполнять обратный импорт из корня __init__.py.

Как тебе это сделать?

  • объявить дб в соответствующем модуле (db.py)
  • импортировать внутри фабрика приложений

Я неохотно относился к этому шаблону, я думал, что эти import утверждения не принадлежат функции. Но это путь.

Итак, ваши файлы должны выглядеть примерно так:

приложение / общий / db.py

from flask_pymongo import PyMongo
mongo = PyMongo

приложение / __ __ INIT. Ру

from flask import Flask
...

def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    from app.common.db import mongo
    mongo.init_app(app)
    ...

и когда вам нужно ваше соединение с базой данных, т.е. в модуле ресурсов, вы должны импортировать его как

from app.common.db import mongo

Примечание: чтобы избежать будущих проблем, ваши чертежи также должны быть объявлены в другом месте и импортированы во время создания. Я настоятельно рекомендую вам прочитать пост от Lepture , чтобы лучше понять этот подход.

...