I'm trying to use alembic which is an sqlalchemy tool in python. You type a command and it generates a folder "alembic" with py files inside. The py file inside, needs to link to my application in a separate folder called "myapp". But I cannot link it. It says it doesn't exist and relative import doesn't work.
so I need to import my config class from myapp/configs/config.py file.
/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.
inside env.py:
from myapp.configs import DefaultConfig
Doesn't work.
I tried:
from ..myapp.configs import DefaultConfig
No success.
example code in alembic docs say just use "myapp.whatever".
I even added my "/apps" and "/myapp" to PYTHON_PATH in environment variables.
Example 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 <module>
from ..myapp.configs import DefaultConfig as conf
ValueError: Attempted relative import in non-package
You have two possible solutions to your problem:
Modify your PYTHONPATH environment variable
Add the path to apps catalogue by running following BASH / SH shell commands in your terminal:
$ export PYTHONPATH=$PYTHONPATH:'/path/to/apps'
Please not that adding it to the PATH environment variable won't work. To find out more about PYTHONPATH, how to manage it plus nice and friendly info on modules in general:
http://www.stereoplex.com/blog/understanding-imports-and-pythonpath
Please note however that this approach does affect your system's PYTHONPATH. It is highly recommended to use a virtualenv - just in case things go wrong, it won't affect all your system and other apps. When using virtualenvwrapper:
$ add2virtualenv '/path/to/apps'
More HERE.
Append path from inside the Python script
Alternatively, you can do the same but just for a script runtime by adding:
import sys
sys.path.append('/path/to/apps')
to your apps/alembic/env.py
file.
Finally, in same file, make a following change:
from myapp.configs.config import DefaultConfig
And please note that your apps/myapp
folder should also contain __init__.py
file (might be empty) to make Python to treat is as a module as Demian Brecht pointed out.
Is myapp
a self-contained application, or a sub-application such as ones that you can find using Django? If it's a self-contained app, then you're kinda going about things wrong. What you really want to do is to install the dependencies that your app has in order to be able to access them without having to use relative imports and the like (which is bad practice, especially if anyone but you is using the app).
What you likely will want to do (again, if it's self-contained):
- Set up a virtual environment for your app (I highly recommend the use of virtualenvwrapper, which I just wrote about in my shiny new (and incomplete) blog: http://demianbrecht.github.com/posts/2013/01/02/virtualenvwrapper/
- Install
alembic
as a dependency: pip install alembic
- Create a
requirements.txt
file: pip freeze > requirements.txt
Now, you should be able to use alembic via import alembic
from anywhere within your project.
Edit:
Your directory structure is also a little wonky. You'll want to put all of your app-specific modules into another myapp
subdirectory:
myapp
myapp
__init__.py
configs/__init__.py
The reason for this is so that you can add myapp
to your PYTHONPATH
and be able to import any modules from your app via from myapp import foo
. As it stands, if myapp
is on your PYTHONPATH
, you'll only be able to access the submodules from the second namespace level (i.e. import configs
), which is bad for obvious reasons.