Alembic 是用来完成 SQLalchemy 数据表迁移的工具,同时也提供了自动生成迁移的选项来简化工作。不过在和 SQLite 协作时,由于SQLite并不是支持所有的SQL命令,所以有一些需要注意的地方,记在这里。
启用Alembic
具体见文档,主要有以下几步
- 初始化环境
- 修改ini文件,最主要的一项是把DB的位置改对。
然后就可以写migrate脚本了。
启用 AutoGenerate
上面教程页面中的Migration需要自己写,不过Alembic还提供了自动生成Migration的选项,首先上文档。
如果需要支持auto,需要做下面的几件事情:
- 在
alembic/env.py
中找target_metadata
,默认生成的是这样:
# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
target_metadata = None
看注释,如果需要支持autogenerate
,把代码改成注释中的样子。注意,如果Base不是放在根目录下,而是在子目录中的,像我这个的结构:
.
├── README.md
├── alembic
│ ├── README
│ ├── env.py
│ ├── script.py.mako
│ └── versions
│ └── XXXXXXXX_foobar.py
├── alembic.ini
├── db
│ └── foobar.db
├── foo.py
├── main.py
├── models
│ ├── __init__.py
│ ├── base.py
│ └── foobar.py
└── requirements.txt
则需要在导入Base前加上这两句:
import os, sys
sys.path.append(os.getcwd())
要不然报找不到的错,嗯。
- 改Model
- 运行
alembic revision --autogenerate -m "blah blah blah ..."
在运行成功后,会在versions目录下生成一个新的migration,所有自动生成的语句都会放在注释中间方便review。
和SQLite一起用
由于SQLite支持的SQL命令不全,所以有些命令,如ALTER TABLE
之类的不能用。好在Alembic在版本0.7.0后,增加了batch的选项,它会根据新的Model创建一个Schema,然后把老的数据移过来。具体的做法就是在 alembic/env.py
的函数 run_migrations_online
函数中,找到 context.configure()
函数,在其中加入 render_as_batch=True
选项即可。不过在github上看到一个更灵活的办法:
context.configure(
connection=connection,
target_metadata=target_metadata,
render_as_batch=config.get_main_option('sqlalchemy.url').startswith('sqlite:///'),
)
这样只在sqlite数据库的时候会用batch,其它就不会了。
暂时就这些,反正只是保证能用了,也没管后面的原理,回头有需求的话再深挖吧。