在Setuptools setup.py
文件中打包Alembic迁移文件的正确方法是什么?一切都在我的回购根目录alembic/
。
这是一个Python应用程序,而不是库。
我想要的安装流程是有人可以pip install
我的应用程序的轮子。然后,他们可以通过运行类似<app> alembic upgrade --sqlalchemy.url=<db_url>
的内容来初始化应用程序数据库。升级将需要pip install -U
,之后他们可以再次运行Alembic命令。
这是非正统的吗?
如果没有,我将如何做到这一点?当然是console_scripts
entry_points
。但除此之外?
答案 0 :(得分:2)
我不确定这是正确的方法,但是我是这样做的:
首先,您可以使用-x选项向alembic添加各种自定义选项,并且可以找到this great answer中介绍的详细信息。这样,您可以在运行时指定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>
这允许在我的package_data
中使用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/**/*'],
},
[...]
)
至此,对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
[...]
最后,您必须使用alembic
选项调用-c
,该选项允许提供配置文件的路径:
alembic -c <path to alembic.ini> ...
答案 1 :(得分:1)
一种将主alembic文件夹保持在主包文件夹中的方法是将alembic文件夹视为要在主软件包旁边安装的自有软件包。
为此,您必须重命名它(它不能被称为alembic
,因为它将是一个顶级程序包,因此需要一个唯一的名称-我用过migrations
),并且在alembic文件夹和版本文件夹中添加一个__init__.py
文件。
在部署中运行迁移需要知道已安装软件包的路径-一种简单的方法是提供一个应用迁移的控制台脚本。
所以项目结构如下:
<project root>
├── setup.py
├── mypackage
│ └── <project source files...>
│
├── migrations
│ ├── __init__.py
│ ├── alembic.ini
│ ├── apply.py
│ ├── env.py
│ ├── README
│ ├── script.py.mako
│ └── versions
│ ├── __init__.py
│ ├── 58c8dcd5fbdc_revision_1.py
│ └── ec385b47da23_revision_2.py
│
└── <other files and dirs>
还有setup.py
:
from setuptools import find_packages
from setuptools import setup
setup(
name='mypackage',
packages=find_packages(exclude=('tests',)),
package_data={'migrations': ['alembic.ini']},
entry_points={
'console_scripts': ['apply-migrations=migrations.apply:main'],
},
install_requires=[
"SQLAlchemy==1.3.0",
"alembic==1.0.10",
# ...
]
)
最后是migrations/apply.py
:
# Python script that will apply the migrations up to head
import alembic.config
import os
here = os.path.dirname(os.path.abspath(__file__))
alembic_args = [
'-c', os.path.join(here, 'alembic.ini'),
'upgrade', 'head'
]
def main():
alembic.config.main(argv=alembic_args)
现在,安装好车轮后,您将拥有一个apply-migrations
命令,可以直接调用它。请注意,我在这里实现的版本没有任何参数-尽管如果您想传递例如。 --sqlalchemy.url
,您可以将其添加到alembic_args
。
我个人更喜欢在migrations/env.py
中设置URL。例如,如果您有一个名为SQLACLHEMYURL
的环境变量,则可以在migrations/env.py
中添加它:
import os
config.set_main_options(os.getenv('SQLALCHEMYURL'))
然后您可以调用:
SQLALCHEMYURL=... apply-migrations
正在部署。