Python学习笔记:Flask-Migrate基于model做upgrade的基本原理
1)flask-migrate的官网:https://flask-migrate.readthedocs.io/en/latest/
2)获取帮助,在pycharm的控制台中输入 flask db --help,或者flask db migrate --help,这样就可以了解各个命令的信息了
3)一般用法,
>flask db init
>flask db migrate
>flask db upgrade
后续对脚本有任何的修改,只要重复执行后两句就可以了。
4)测试1:添加一行数据,删除email列,然后再加上
针对下面这个表:
1 class User(db.Model): 2 __tablename__ = 'user' 3 id = db.Column(db.Integer,primary_key=True) 4 username = db.Column(db.String(64),index=True,unique=True) 5 email = db.Column(db.String(120),index=True,unique=True) 6 password_hash = db.Column(db.String(128)) 7 8 def __repr__(self): 9 return '<用户名:{}>'.format(self.username)
a)先通过以上3个命令创建表;
b)然后再数据库中插入一条数据;
c)然后从models中把email列删除,执行migrate ,updrade,此时发现,数据还在,只是列删除了;
d)然后恢复email列,执行migrate,upgrade,此时发现,数据还在,增加了一个email的空列;
仔细观察日志,发现这个upgrade执行的是升级,而不是重新创建
INFO [alembic.runtime.migration] Running upgrade 04a26df9c6d3 -> 04f13e3c2f7e, empty message
其中04a26df9c6d3_.py的内容为:
1 """empty message 2 Revision ID: 04a26df9c6d3 3 Revises: 4ed84444672c 4 Create Date: 2018-08-29 07:14:44.779039 5 """ 6 from alembic import op 7 import sqlalchemy as sa 8 9 10 # revision identifiers, used by Alembic. 11 revision = '04a26df9c6d3' 12 down_revision = '4ed84444672c' 13 branch_labels = None 14 depends_on = None 15 16 17 def upgrade(): 18 # ### commands auto generated by Alembic - please adjust! ### 19 op.drop_index('ix_user_email', table_name='user') 20 op.drop_column('user', 'email') 21 # ### end Alembic commands ### 22 23 24 def downgrade(): 25 # ### commands auto generated by Alembic - please adjust! ### 26 op.add_column('user', sa.Column('email', sa.VARCHAR(length=120), autoincrement=False, nullable=True)) 27 op.create_index('ix_user_email', 'user', ['email'], unique=True) 28 # ### end Alembic commands ###
04f13e3c2f7e_.py 的内容为
1 """empty message 2 3 Revision ID: 04f13e3c2f7e 4 Revises: 04a26df9c6d3 5 Create Date: 2018-08-29 07:19:33.876815 6 7 """ 8 from alembic import op 9 import sqlalchemy as sa 10 11 12 # revision identifiers, used by Alembic. 13 revision = '04f13e3c2f7e' 14 down_revision = '04a26df9c6d3' 15 branch_labels = None 16 depends_on = None 17 18 19 def upgrade(): 20 # ### commands auto generated by Alembic - please adjust! ### 21 op.add_column('user', sa.Column('email', sa.String(length=120), nullable=True)) 22 op.create_index(op.f('ix_user_email'), 'user', ['email'], unique=True) 23 # ### end Alembic commands ### 24 25 26 def downgrade(): 27 # ### commands auto generated by Alembic - please adjust! ### 28 op.drop_index(op.f('ix_user_email'), table_name='user') 29 op.drop_column('user', 'email') 30 # ### end Alembic commands ###
5)测试2:把user表删除
a)如果只执行flask db upgrade,则什么都不执行
(venv) D:\WORK\gitbase\HelloFlask>flask db upgrade
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
b)执行flask db migrate,然后再执行flask db upgrade,则可以重新创建表
通过migrate,程序会先比较本地的model和数据库中实际的表,然后创建如下脚本 69f5e753ee6c_.py
1 """empty message 2 3 Revision ID: 69f5e753ee6c 4 Revises: 04f13e3c2f7e 5 Create Date: 2018-08-29 07:31:19.236320 6 7 """ 8 from alembic import op 9 import sqlalchemy as sa 10 11 12 # revision identifiers, used by Alembic. 13 revision = '69f5e753ee6c' 14 down_revision = '04f13e3c2f7e' 15 branch_labels = None 16 depends_on = None 17 18 19 def upgrade(): 20 # ### commands auto generated by Alembic - please adjust! ### 21 op.create_table('user', 22 sa.Column('id', sa.Integer(), nullable=False), 23 sa.Column('username', sa.String(length=64), nullable=True), 24 sa.Column('email', sa.String(length=120), nullable=True), 25 sa.Column('password_hash', sa.String(length=128), nullable=True), 26 sa.PrimaryKeyConstraint('id') 27 ) 28 op.create_index(op.f('ix_user_email'), 'user', ['email'], unique=True) 29 op.create_index(op.f('ix_user_username'), 'user', ['username'], unique=True) 30 # ### end Alembic commands ### 31 32 33 def downgrade(): 34 # ### commands auto generated by Alembic - please adjust! ### 35 op.drop_index(op.f('ix_user_username'), table_name='user') 36 op.drop_index(op.f('ix_user_email'), table_name='user') 37 op.drop_table('user') 38 # ### end Alembic commands ###
6)结论
对模型的任何修改,都要再执行flask db migrate, flask db upgrade
这里做的任何的更新,实际上都是把模型和数据库当前的状态做比较的
而且历次的版本都有,所以实际上可以回退到之前的任何一个版本。
这个思路其实挺好,这就是我们之前写数据库补丁脚本的思路,一环套一环,只不过之前是靠人的,现在是靠程序自动生成的。
而且他这里更好的地方是,不但支持upgrade,还支持downgrade