Относительный импорт модуля python из подпапки из другой подпапки

Я пытаюсь использовать alembic, который является инструментом sqlalchemy в python. Вы вводите команду, и она создает папку «перегонный куб» с файлами py внутри. Файл py внутри должен быть связан с моим приложением в отдельной папке с именем «myapp». Но не могу связать. Он говорит, что он не существует, и относительный импорт не работает.

поэтому мне нужно импортировать класс конфигурации из файла myapp/configs/config.py.

/apps
+--/alembic
|----env.py <--- the calling file
+--/myapp
|----configs/__init__.py <--- has "DefaultConfig" class imported
|----configs/config.py <--- I want to import the class inside here.

внутри env.py:

from myapp.configs import DefaultConfig

Не работает.

Я пытался:

from ..myapp.configs import DefaultConfig

Нет успеха.

пример кода в документах перегонного куба говорит, что просто используйте «myapp.whatever».

Я даже добавил свои «/apps» и «/myapp» в PYTHON_PATH в переменных среды.

Пример ошибки:

File "D:\apps\myapp\lib\site-packages\alembic\command.p
y", line 97, in revision
    script.run_env()
  File "D:\apps\myapp\lib\site-packages\alembic\script.py
", line 191, in run_env
    util.load_python_file(self.dir, 'env.py')
  File "D:\apps\myapp\lib\site-packages\alembic\util.py",
 line 186, in load_python_file
    module = imp.load_source(module_id, path, open(path, 'rb'))
  File "alembic\env.py", line 5, in <module>
    from ..myapp.configs import DefaultConfig as conf
ValueError: Attempted relative import in non-package

person Dexter    schedule 04.02.2013    source источник
comment
Я запутался, вы запускали setup.py для проекта?   -  person Greg    schedule 04.02.2013
comment
После того, как я pip install alembic... Я сделал alembic init alembic, и он сгенерировал файлы.   -  person Dexter    schedule 04.02.2013
comment
Попробуйте добавить '../myapp' к sys.path Python в env.py перед импортом.   -  person martineau    schedule 04.02.2013


Ответы (2)


У вас есть два возможных решения вашей проблемы:

Измените переменную среды PYTHONPATH.

Добавьте путь к каталогу приложений, выполнив следующие команды оболочки BASH / SH в своем терминале:

$ export PYTHONPATH=$PYTHONPATH:'/path/to/apps'

Обратите внимание, что добавление его в переменную окружения PATH не сработает. Чтобы узнать больше о PYTHONPATH, о том, как им управлять, а также полезную и полезную информацию о модулях в целом:

http://www.stereoplex.com/blog/understanding-imports-and-pythonpath

Обратите внимание, однако, что этот подход влияет на PYTHONPATH вашей системы. Настоятельно рекомендуется использовать virtualenv — на случай, если что-то пойдет не так, это не повлияет на всю вашу систему и другие приложения. При использовании virtualenvwrapper:

$ add2virtualenv '/path/to/apps'

Подробнее ЗДЕСЬ.

Добавить путь изнутри скрипта Python

В качестве альтернативы вы можете сделать то же самое, но только для среды выполнения скрипта, добавив:

import sys
sys.path.append('/path/to/apps')

в ваш файл apps/alembic/env.py.

Наконец, в том же файле внесите следующие изменения:

from myapp.configs.config import DefaultConfig

И обратите внимание, что ваша папка apps/myapp также должна содержать файл __init__.py (может быть пустым), чтобы Python рассматривался как модуль, как указал Демиан Брехт.

person Kulbi    schedule 13.05.2013
comment
Работал на меня! Предполагается ли, что папка перегонного куба по умолчанию находится внутри модуля приложения? Это кажется странным поведением. Кроме того, чтобы избежать этого трудного пути import sys,os sys.path.append(os.getcwd()) - person agentargo; 12.09.2013

Является ли myapp автономным приложением или подприложением, которое вы можете найти с помощью Django? Если это автономное приложение, то вы что-то делаете не так. То, что вы действительно хотите сделать, это установить зависимости, которые есть у вашего приложения, чтобы иметь возможность доступа к ним без использования относительного импорта и тому подобного (что является плохой практикой, особенно если кто-то, кроме вас использует приложение).

Что вы, вероятно, захотите сделать (опять же, если это автономно):

  • Настройте виртуальную среду для своего приложения (я настоятельно рекомендую использовать virtualenvwrapper, о котором я только что писал в своем блестящем новом (и незавершенном) блоге: http://demianbrecht.github.com/posts/2013/01/02/virtualenvwrapper/
  • Установите alembic как зависимость: pip install alembic
  • Создайте файл requirements.txt: pip freeze > requirements.txt

Теперь вы сможете использовать alembic через import alembic из любого места вашего проекта.

Изменить:

Ваша структура каталогов также немного шаткая. Вы захотите поместить все модули, относящиеся к вашему приложению, в другой подкаталог myapp:

myapp
    myapp
        __init__.py
        configs/__init__.py

Причина этого в том, что вы можете добавить myapp к вашему PYTHONPATH и иметь возможность импортировать любые модули из вашего приложения через from myapp import foo. В нынешнем виде, если myapp находится на вашем PYTHONPATH, вы сможете получить доступ к подмодулям только со второго уровня пространства имен (то есть import configs), что по очевидным причинам плохо.

person Demian Brecht    schedule 04.02.2013
comment
Это приложение Flask. Ну, я не уверен, как еще получить alembic, чтобы найти мой файл конфигурации и получить из него URI DB SQL. В примере говорится просто выполнить app.config[SQLALCHEMY_URI] или что-то в этом роде, но не указано, как получить приложение. Выдается ошибка ПОСЛЕ того, как я запускаю «перегонную проверку --autogenerate -m test», чтобы я мог создать свои первоначальные модели. - person Dexter; 04.02.2013
comment
Вы можете использовать from flask get current_app для получения app, пока вы находитесь в контексте запроса. - person Demian Brecht; 04.02.2013
comment
Ну, вы бы использовали перегонный куб только при выполнении команд, когда веб-сайт даже находится в автономном режиме, поэтому это должен быть контекст приложения. Я думаю, мне нужен какой-то новый код, например, в flask-alembic - person Dexter; 04.02.2013