如果 drop_all; create_all 不会给我留下架构更改,我想跳过这两行。
我怎样才能做到这一点?
背景:我使用 SQLite 来缓存和保存代码更改的数据是不值得的,但是如果缓存了东西并且同时没有发生代码或数据库更改,我想保留缓存的数据并使用它。
注意:现在这个问题具有学术兴趣,因为我的团队接受了“开发人员必须关心迁移”的解决方案。我仍然对如何检测实际的 db-schema 是否与实体派生的 db-schema 匹配感兴趣。
如果 drop_all; create_all 不会给我留下架构更改,我想跳过这两行。
我怎样才能做到这一点?
背景:我使用 SQLite 来缓存和保存代码更改的数据是不值得的,但是如果缓存了东西并且同时没有发生代码或数据库更改,我想保留缓存的数据并使用它。
注意:现在这个问题具有学术兴趣,因为我的团队接受了“开发人员必须关心迁移”的解决方案。我仍然对如何检测实际的 db-schema 是否与实体派生的 db-schema 匹配感兴趣。
在您的数据库中创建一个版本表,该表存储模式的版本号,然后将该数字与您的应用程序中的数字核对。
这与alembic等架构迁移工具使用的方法相同。使用真正的迁移工具并仅调用“升级”而不是“create_all()”将是这里的最佳实践。
比较模式不是一项简单的任务 - alembic 实际上包含一个提供此功能的功能,您也可以在 API 级别访问该功能,但它有很多警告,并且在生成新的迁移脚本时更能节省时间。
编辑:Alembic 的 api:compare_metadata
例子:
from alembic.migration import MigrationContext
from alembic.autogenerate import compare_metadata
from sqlalchemy.schema import SchemaItem
from sqlalchemy.types import TypeEngine
from sqlalchemy import (create_engine, MetaData, Column,
Integer, String, Table)
import pprint
engine = create_engine("sqlite://")
engine.execute('''
create table foo (
id integer not null primary key,
old_data varchar,
x integer
)''')
engine.execute('''
create table bar (
data varchar
)''')
metadata = MetaData()
Table('foo', metadata,
Column('id', Integer, primary_key=True),
Column('data', Integer),
Column('x', Integer, nullable=False)
)
Table('bat', metadata,
Column('info', String)
)
mc = MigrationContext.configure(engine.connect())
diff = compare_metadata(mc, metadata)
pprint.pprint(diff, indent=2, width=20)
输出:
[ ( 'add_table',
Table('bat', MetaData(bind=None),
Column('info', String(), table=<bat>), schema=None)),
( 'remove_table',
Table(u'bar', MetaData(bind=None),
Column(u'data', VARCHAR(), table=<bar>), schema=None)),
( 'add_column',
None,
'foo',
Column('data', Integer(), table=<foo>)),
( 'remove_column',
None,
'foo',
Column(u'old_data', VARCHAR(), table=None)),
[ ( 'modify_nullable',
None,
'foo',
u'x',
{ 'existing_server_default': None,
'existing_type': INTEGER()},
True,
False)]]