MrO*_*Sir 13 python sqlalchemy alembic
我有以下项目结构
--some db:
--some db:
--alchemy:
-- __init__.py
--alembic:
-- versions
-- env.py
-- README.py
-- script.py
--migrations:
-- __init__.py
--models:
-- model_1
-- model_2
-- __init__.py
Run Code Online (Sandbox Code Playgroud)
我尝试通过 alembic 自动生成迁移。
我Base在__init__.py模型中的文件夹
import sqlalchemy as sa
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base, declared_attr
metadata = sa.MetaData()
Base = declarative_base(metadata=metadata)
Run Code Online (Sandbox Code Playgroud)
并导入这是 env.py
from logging.config import fileConfig
from alembic import context
from sqlalchemy import engine_from_config
from sqlalchemy import pool
from models import Base
config = context.config
fileConfig(config.config_file_name)
target_metadata = Base.metadata
Run Code Online (Sandbox Code Playgroud)
因此,当我从 alembic 目录中的 env.py 中的模型导入 Base 并尝试生成自动迁移时,我遇到了一些错误,例如
ModuleNotFoundError: 没有名为“models”的模块
我该如何解决这个错误?
dar*_*all 28
问题是env.py执行时,models不在您的 中PYTHONPATH,因此无法导入。
根据您概述的项目结构,可能有点难以解决;最简单的解决方案可能是像这样修改你的PYTHONPATH内部env.py:
import sys
sys.path = ['', '..'] + sys.path[1:]
from models import Base
Run Code Online (Sandbox Code Playgroud)
这会将 的父目录添加alembic/到您的目录中,PYTHONPATH以便它可以找到该models模块。
或者,将包含模块的目录添加到PYTHONPATHshell 中的环境变量中:
$ export PYTHONPATH='/path/to/some db/some db':$PYTHONPATH
Run Code Online (Sandbox Code Playgroud)
此解决方案有点脆弱,因为您必须记住每个会话都执行此操作,并且您打算在其上运行 Alembic 的每台机器都会有所不同。
当我遇到这个问题时,SQLAlchemy 开发人员建议如果我使用pip虚拟环境,我可以在可编辑模式下安装我的项目,以便它在系统中PYTHONPATH并且 Alembic 可以从任何地方找到它。Python 打包指南中提供了更多详细信息。为此,您setup.py的项目需要一个,并且您可能希望更改项目结构,以便有一个包含models和等内容的顶级模块alchemy。例如:
myproj/
setup.py
alembic/
env.py
migrations/
myapp/
__init__.py
alchemy/
__init__.py
models/
__init__.py
Run Code Online (Sandbox Code Playgroud)
如果设置正确,您可以
myproj/
setup.py
alembic/
env.py
migrations/
myapp/
__init__.py
alchemy/
__init__.py
models/
__init__.py
Run Code Online (Sandbox Code Playgroud)
从myproj/目录内部。然后env.py你会Base像这样导入:
$ pip install -e .
Run Code Online (Sandbox Code Playgroud)
小智 25
现在有一个漂亮的方法:https://github.com/sqlalchemy/alembic/commit/d6b0c1af3df98b50c6ec52781aa411592c4e0c32
“...默认的“alembic.ini”文件包含一个指令prepend_sys_path = .,因此本地路径也在sys.path.
小智 6
当模块从 Python 中的文件加载时,__file__设置为其路径。然后,您可以将其与其他函数一起使用以查找文件所在的目录。
在 alembic/env.py 文件中添加以下行以解决 ModuleNotFoundError
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
Run Code Online (Sandbox Code Playgroud)