阿伦比克.ModuleNotFoundError in env.py.



我有以下项目结构

--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

我尝试通过 alembic 自动生成迁移。

我在模型文件夹中__init__.pyBase

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)

导入这是 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

因此,当我从 alembic 目录中的 env.py 模型中导入 Base 并尝试生成自动迁移时,我遇到了一些错误,例如

ModuleNotFoundError:没有名为"models"的模块

如何修复此错误?

问题是当执行env.py时,models不在您的PYTHONPATH中,因此无法导入。

使用您概述的项目结构,可能有点难以解决;最简单的解决方案可能是像这样修改env.py内部的PYTHONPATH

import sys
sys.path = ['', '..'] + sys.path[1:]
from models import Base

这会将alembic/的父目录添加到您的PYTHONPATH,以便它可以找到models模块。

或者,将包含模块的目录添加到 shell 中的PYTHONPATH环境变量中:

$ export PYTHONPATH='/path/to/some db/some db':$PYTHONPATH

这个解决方案有点脆弱,因为你必须记住每个会话都这样做,并且对于你打算运行Alembic的每台机器来说,它会有所不同。

当我遇到这个问题时,SQLAlchemy 开发人员建议,如果我使用pip和虚拟环境,我可以在可编辑模式下安装我的项目,以便它在系统中PYTHONPATH并且 Alembic 能够从任何地方找到它。有关更多详细信息,请参阅 Python 打包指南。为此,您需要为项目提供一个setup.py,并且您可能希望更改项目结构,以便有一个包含modelsalchemy等内容的顶级模块。例如:

myproj/
setup.py
alembic/
env.py
migrations/
myapp/
__init__.py
alchemy/
__init__.py
models/
__init__.py

如果设置正确,您可以

$ pip install -e .

myproj/目录中。然后在env.py中,您将导入如下Base

from myapp.models import Base

现在有一个漂亮的方法:https://github.com/sqlalchemy/alembic/commit/d6b0c1af3df98b50c6ec52781aa411592c4e0c32

"...默认的"alembic.ini"文件包含一个指令prepend_sys_path = .以便本地路径也在sys.path中。

当从 Python 中的文件加载模块时,__file__设置为其路径。然后,您可以将其与其他函数一起使用,以查找文件所在的目录。

在 alembic/env.py 文件中添加以下行以解决 ModuleNotFoundError

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)

我找到了以下适用于 Linux 的解决方案,我觉得这很容易。 按以下方式运行 cmd:

PYTHONPATH={your python path} {your alembic cmd}

我将alembic作为python模块运行,例如:

python3 -m alembic.config upgrade head

我其次@Abhishek Dhotre的anwer,因为这种方法对于开发人员可能拥有的各种项目结构都更通用,就我而言,当我运行uvicorn main:app --reload我得到No module named app

。我通过在env.py中包含sys.path.append(path_to_app)来解决它,其中path_to_app相对于env.py的位置,如下所示:

env.py

import sys
import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
APP_DIR = os.path.join(BASE_DIR, '../app')
sys.path.append(APP_DIR)

最新更新