Módulo de importación de Python relativo desde una subcarpeta desde una subcarpeta diferente

Estoy tratando de usar un alambique que es una herramienta sqlalchemy en python. Escribe un comando y genera una carpeta “alambique” con archivos py en su interior. El archivo py en el interior, debe vincularse a mi aplicación en una carpeta separada llamada “myapp”. Pero no puedo vincularlo. Dice que no existe y que la importación relativa no funciona.

así que necesito importar mi clase de configuración del archivo 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. 

dentro de env.py:

 from myapp.configs import DefaultConfig 

No funciona

Lo intenté:

 from ..myapp.configs import DefaultConfig 

Sin éxito.

el código de ejemplo en documentos de alambique dice que solo use “myapp.whatever”.

Incluso agregué mi “/ apps” y “/ myapp” a PYTHON_PATH en las variables de entorno.

Ejemplo de error:

 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  from ..myapp.configs import DefaultConfig as conf ValueError: Attempted relative import in non-package 

Tienes dos posibles soluciones a tu problema:

Modificar su variable de entorno PYTHONPATH

Agregue la ruta al catálogo de aplicaciones ejecutando los siguientes comandos de shell de BASH / SH en su terminal:

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

Por favor, tenga en cuenta que agregarlo a la variable de entorno PATH no funcionará. Para obtener más información sobre PYTHONPATH, cómo administrarlo más información agradable y amigable sobre los módulos en general:

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

Tenga en cuenta, sin embargo, que este enfoque afecta a PYTHONPATH de su sistema. Se recomienda encarecidamente utilizar un virtualenv: en caso de que las cosas salgan mal, no afectará a todo su sistema ni a otras aplicaciones. Cuando se utiliza virtualenvwrapper:

 $ add2virtualenv '/path/to/apps' 

Más AQUÍ .

Anexar ruta desde dentro del script de Python

Alternativamente, puede hacer lo mismo pero solo para un tiempo de ejecución de script agregando:

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

a su apps/alembic/env.py archivo.

Finalmente, en el mismo archivo, haga un cambio siguiente:

 from myapp.configs.config import DefaultConfig 

Y tenga en cuenta que su carpeta de apps/myapp también debe contener el archivo __init__.py (podría estar vacío) para que Python sea __init__.py como un módulo, como lo señaló Demian Brecht.

¿Es myapp una aplicación autónoma, o una sub-aplicación como las que puedes encontrar usando Django? Si es una aplicación autocontenida, entonces estás haciendo las cosas mal. Lo que realmente quiere hacer es instalar las dependencias que tiene su aplicación para poder acceder a ellas sin tener que usar importaciones relativas y similares (lo que es una mala práctica, especialmente si alguien que no sea usted utiliza la aplicación).

Lo que probablemente querrás hacer (de nuevo, si es auto contenido):

  • Configure un entorno virtual para su aplicación ( recomiendo encarecidamente el uso de virtualenvwrapper, sobre el que acabo de escribir en mi shiny blog nuevo (e incompleto): http://demianbrecht.github.com/posts/2013/01/02/ virtualenvwrapper /
  • Instalar alembic como una dependencia: pip install alembic
  • Cree un archivo pip freeze > requirements.txt : pip freeze > requirements.txt

Ahora, debería poder usar alambique mediante la import alembic desde cualquier lugar dentro de su proyecto.

Editar :

Su estructura de directorio es también un poco torpe. Querrá colocar todos los módulos específicos de su aplicación en otro subdirectorio myapp :

 myapp myapp __init__.py configs/__init__.py 

La razón de esto es para que pueda agregar myapp a PYTHONPATH y poder importar cualquier módulo desde su aplicación from myapp import foo . Tal como está, si myapp está en su PYTHONPATH , solo podrá acceder a los submódulos desde el segundo nivel de espacio de nombres (es decir, import configs ), lo cual es malo por razones obvias.