Python - 使用Setuptools打包Alembic迁移

jen*_*wan 11 python setuptools alembic

在Setuptools setup.py文件中打包Alembic迁移文件的正确方法是什么?一切都在我的回购根源中alembic/.

这是一个Python应用程序,而不是库.

我想要的安装流程是有人可以pip install将轮子作为我的应用程序.然后,他们可以通过运行类似的方式来初始化应用程序数据库<app> alembic upgrade --sqlalchemy.url=<db_url>.然后升级将需要a pip install -U,之后他们可以再次运行Alembic命令.

这是非正统的吗?

如果没有,我将如何做到这一点?当然是console_scripts entry_points.但除此之外?

Ali*_*ton 6

将 alembic 文件夹保留在主包文件夹中的一种方法是将 alembic 文件夹视为它自己的包,与主包一起安装。

\n\n

为此,您必须重命名它(它不能被调用alembic,因为它将是一个顶级包,因此需要一个唯一的名称 - 我已经使用过migrations),并__init__.py在 alembic 文件夹和 versions 文件夹中添加一个文件。

\n\n

在部署上运行迁移需要知道已安装包的路径 - 一种简单的方法是提供应用迁移的控制台脚本。

\n\n

所以项目结构如下所示:

\n\n
<project root>\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 setup.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 mypackage\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 <project source files...>\n\xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 migrations\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 alembic.ini\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 apply.py\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 env.py\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 README\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 script.py.mako\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 versions\n\xe2\x94\x82       \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82       \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 58c8dcd5fbdc_revision_1.py\n\xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ec385b47da23_revision_2.py\n\xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 <other files and dirs>\n
Run Code Online (Sandbox Code Playgroud)\n\n

setup.py

\n\n
<project root>\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 setup.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 mypackage\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 <project source files...>\n\xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 migrations\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 alembic.ini\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 apply.py\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 env.py\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 README\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 script.py.mako\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 versions\n\xe2\x94\x82       \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82       \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 58c8dcd5fbdc_revision_1.py\n\xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ec385b47da23_revision_2.py\n\xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 <other files and dirs>\n
Run Code Online (Sandbox Code Playgroud)\n\n

最后migrations/apply.py

\n\n
from setuptools import find_packages\nfrom setuptools import setup\n\n\nsetup(\n    name=\'mypackage\',\n    packages=find_packages(exclude=(\'tests\',)),\n    package_data={\'migrations\': [\'alembic.ini\']},\n    entry_points={\n        \'console_scripts\': [\'apply-migrations=migrations.apply:main\'],\n    },\n    install_requires=[\n        "SQLAlchemy==1.3.0",\n        "alembic==1.0.10",\n        # ...\n    ]\n)\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在安装轮子后,您将拥有一个apply-migrations可以直接调用的命令。请注意,我在这里实现的版本没有任何参数 - 尽管如果您想通过例如。--sqlalchemy.url你可以将它添加到alembic_args.

\n\n

我个人更喜欢将 url 设置为migrations/env.py. 例如,如果您有一个名为的环境变量,SQLACLHEMYURL您可以将其添加到migrations/env.py

\n\n
# Python script that will apply the migrations up to head\nimport alembic.config\nimport os\n\nhere = os.path.dirname(os.path.abspath(__file__))\n\nalembic_args = [\n    \'-c\', os.path.join(here, \'alembic.ini\'),\n    \'upgrade\', \'head\'\n]\n\n\ndef main():\n    alembic.config.main(argv=alembic_args)\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后你可以调用:

\n\n
SQLALCHEMYURL=... apply-migrations\n
Run Code Online (Sandbox Code Playgroud)\n\n

正在部署中。

\n


Try*_*yph 5

我不确定这是正确的方法,但我是这样做的:

首先,您可以使用 -x 选项向 alembic 添加某种自定义选项,您可以在这个很好的答案中找到详细说明。这允许您db_url在运行时指定并使其覆盖config.ini.

然后我设法通过将alembic.ini文件和alembic目录从我的项目根目录移动到我的顶级 python 包来打包 alembic 和我的迁移:

<project root>
??? src
?   ??? <top-level package dir>
?       ??? alembic
?       ?   ??? env.py
?       ?   ??? README
?       ?   ??? script.py.mako
?       ?   ??? versions
?       ?       ??? 58c8dcd5fbdc_revision_1.py
?       ?       ??? ec385b47da23_revision_2.py
?       ??? alembic.ini
?       ??? __init__.py
?       ??? <other files and dirs>
??? <other files and dirs>
Run Code Online (Sandbox Code Playgroud)

这允许package_data在 my 中使用 setuptools指令setup.py

setup(
    name=<package_name>,
    package_dir={'': 'src'},
    packages=find_packages(where='src'),
    package_data={
        '<top-level package dir>': ['alembic.ini', 'alembic/*', 'alembic/**/*'],
    },
    [...]
)  
Run Code Online (Sandbox Code Playgroud)

在这一点上,alembic 配置和修订版已正确打包,但alembic.ini必须调整设置以反映新的目录树。可以使用%(here)s包含alembic.ini文件所在目录的绝对路径的参数来完成:

# A generic, single database configuration.

[alembic]
# path to migration scripts
script_location = %(here)s/alembic

[...]

# version location specification; this defaults
# to alembic/versions.  When using multiple version
# directories, initial revisions must be specified with --version-path
# version_locations = %(here)s/bar %(here)s/bat alembic/versions
version_locations = %(here)s/alembic/versions

[...]
Run Code Online (Sandbox Code Playgroud)

最后,您必须alembic使用-c允许提供配置文件路径的选项进行调用:

alembic -c <path to alembic.ini> ...
Run Code Online (Sandbox Code Playgroud)