【问题标题】:Alembic. ModuleNotFoundError in env.py蒸馏器。 env.py 中的 ModuleNotFoundError
【发布时间】:2019-12-19 10:38:47
【问题描述】:

我有喜欢的项目结构

 --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__.py 中有Base

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: 没有名为“模型”的模块

我该如何解决这个错误?

【问题讨论】:

    标签: python sqlalchemy alembic


    【解决方案1】:

    问题是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 开发人员 suggested 说,如果我使用 pip 和虚拟环境,我可以以可编辑模式安装我的项目,以便它在系统中 PYTHONPATH 并且 Alembic 能够从任何地方找到它。更多详细信息可在Python packaging guide 中找到。为此,您的项目需要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
    

    【讨论】:

    • 我没有用win,但是windows版本应该是`set PYTHONPATH=%PYTHONPATH%;C:\your\path`
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

      "...默认的“alembic.ini”文件包含一个指令prepend_sys_path = .,因此本地路径也在sys.path中。

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-04-11
          • 2020-08-08
          • 2014-03-29
          • 2021-07-23
          • 1970-01-01
          • 2020-03-27
          • 1970-01-01
          • 2021-09-18
          相关资源
          最近更新 更多