flask-migrate动态迁移数据库

作者: 凌烟醉卧 | 来源:发表于2019-01-09 18:32 被阅读4次

    了解flask_migrate需要先了解flask-script,那么flask-script的作用是什么呢?flask-script的作用是可以通过命令行的形式来操作Flask。例如通过命令跑一个开发版本的服务器、设置数据库,定时任务等。

    2.执行pip install flask-script来进行安装。

    1. 如果直接在主manage.py中写命令,那么在终端就只需要python manage.py command_name就可以了。
    2. 如果把一些命令集中在一个文件中,那么在终端就需要输入一个父命令,比如python manage.py db init

    app.py文件

    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    
    if __name__ == '__main__':
        app.run()
    

    manager.py文件

    # encoding: utf-8
    
    from flask_script import Manager
    from app import app
    
    manager = Manager(app)
    
    @manager.command
    def run():
        print("服务器跑起来了")
    
    if __name__ == '__main__':
        manager.run()
    

    在终端运行,run代表的是manager.py中的方法

    python manage.py run
    
    服务器跑起来了
    

    flask-script我们一般和数据库在一起使用

    app.py文件

    #encoding: utf-8
    
    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    manage.py文件

    #encoding: utf-8
    
    from flask import Flask
    
    app = Flask(__name__)
    
    
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    db_scripts.py文件

    # encoding: utf-8
    
    from flask_script import Manager
    
    DBManager = Manager()
    
    @DBManager.command
    def init():
        print('数据库初始化完成')
    
    @DBManager.command
    def migrate():
        print('数据表迁移成功')
    

    首先执行如下命令:

    python manage.py db init
    
    数据库初始化完成
    

    再执行命令

    python manage.py db migrate
    
    数据表迁移成功
    

    上面使用flask-script的使用以及对数据库的演示,实际开发中我们使用flask-migrate来动态的迁移数据库,使用flask-migrate必须借助flask-script。

    Flask-Migrate的介绍与安装:

    pip install flask-migrate
    

    搞起!!!

    migrate_demo.py文件

    from flask import Flask
    import config
    from exts import db
    
    app = Flask(__name__)
    app.config.from_object(config)
    db.init_app(app)
    
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    exts.py文件

    from flask_sqlalchemy import SQLAlchemy
    db = SQLAlchemy()
    

    config.py文件

    DIALECT = 'mysql'
    DRIVER = 'pymysql'
    USERNAME = 'root'
    PASSWORD = '123456'
    HOST = '127.0.0.1'
    PORT = '3306'
    DATABASE = 'pythonflask'
    
    SQLALCHEMY_DATABASE_URI = "{}+{}://{}:{}@{}:{}/{}?charset=utf8".format(DIALECT, DRIVER, USERNAME, PASSWORD, HOST, PORT,
                                                                           DATABASE)
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    

    models.py

    from exts import db
    
    class Article(db.Model):
        __tablename__ = 'article'
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        title = db.Column(db.String(100), nullable=False)
        content = db.Column(db.Text, nullable=False)
    

    manage.py,这个是最重要的文件:

    from flask_script import Manager
    from migrate_demo import app
    from flask_migrate import Migrate,MigrateCommand
    from exts import db
    from models import Article
    
    manager = Manager(app)
    # 1. 要使用flask_migrate,必须绑定app和db
    migrate = Migrate(app,db)
    # 2. 把MigrateCommand命令添加到manager中
    manager.add_command('db',MigrateCommand)
    
    if __name__ == '__main__':
        manager.run()
    

    我们使用的是pythonflask这个数据库,里面没有任何的表和数据。



    • 终端执行命令第一个命令:
    python manage.py db init
    

    上面的命令执行后,在我们的项目中会生成一个migrations文件夹,如下所示,versions中没有任何内容:



    上面的命令执行完后,来看看数据库发生变化没有:



    可以看出,此时数据库没有发生任何变化。
    • 上面的命令成功后,执行如下命令,将模型生成迁移文件:
    python manage.py db init
    

    如下所示,versions文件夹中生成了一个文件c6439ddd759f_.py,这个就是迁移文件。


    c6439ddd759f_.py:

    from alembic import op
    import sqlalchemy as sa
    
    # revision identifiers, used by Alembic.
    revision = 'c6439ddd759f'
    down_revision = None
    branch_labels = None
    depends_on = None
    
    def upgrade():
        # ### commands auto generated by Alembic - please adjust! ###
        op.create_table('article',
        sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
        sa.Column('title', sa.String(length=100), nullable=False),
        sa.Column('content', sa.Text(), nullable=False),
        sa.PrimaryKeyConstraint('id')
        )
        # ### end Alembic commands ###
    
    def downgrade():
        # ### commands auto generated by Alembic - please adjust! ###
        op.drop_table('article')
        # ### end Alembic commands ###
    

    再来看看数据库发生了什么变化:


    这时多了一个alembic_version文件,这个文件是迁移文件的版本号。

    • 接下来执行最后一个命令,将迁移文件真正的映射到数据库中:
    python manage.py db upgrade
    

    查看数据库的变化:


    可以看出,这个命令执行完后,数据才真正的迁移到数据库了。

    现在article中我们可以看到只有如下字段:


    那这时候如果我想再插入一个字段,该如何操作呢?只需要把上面的命令执行一遍就可以,但不是每个命令都执行的。
    python manage.py db init:这个命令不需要执行,因为已经初始化了迁移脚本的环境,这个命令只执行一次。

    python manage.py db migrate:这个命令需要执行,因为模型改变了。

    python manage.py db upgrade这个命令也需要执行,每次运行了migrate命令后,就记得要运行这个命令。

    增加的这个字段为“name”:

    class Article(db.Model):
        __tablename__ = 'article'
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        title = db.Column(db.String(100), nullable=False)
        name = db.Column(db.String(100), nullable=False)
        content = db.Column(db.Text, nullable=False)
    

    命令执行完后,查看数据库:



    更新成功了!!!!!!!

    总结如下:

    1. 介绍:因为采用db.create_all在后期修改字段的时候,不会自动的映射到数据库中,必须删除表,然后重新运行db.craete_all才会重新映射,这样不符合我们的需求。因此flask-migrate就是为了解决这个问题,它可以在每次修改模型后,可以将修改的东西映射到数据库中。
    2. 使用flask_migrate必须借助flask_scripts,这个包的MigrateCommand中包含了所有和数据库相关的命令。
    3. flask_migrate相关的命令:
      • python manage.py db init:初始化一个迁移脚本的环境,只需要执行一次。
      • python manage.py db migrate:将模型生成迁移文件,只要模型更改了,就需要执行一遍这个命令。
      • python manage.py db upgrade:将迁移文件真正的映射到数据库中。每次运行了migrate命令后,就记得要运行这个命令。
    4. 注意点:需要将你想要映射到数据库中的模型,都要导入到manage.py文件中,如果没有导入进去,就不会映射到数据库中。

    最后我们可以随心所欲的来对数据库进行增删改查了,简单的在article中插入一条数据,修改migrate_demo.py文件:

    from flask import Flask
    
    import config
    from exts import db
    from models import Article
    
    app = Flask(__name__)
    app.config.from_object(config)
    db.init_app(app)
    
    #  新增数据
    @app.route('/addData')
    def addData():
        article = Article(title='aaaa', content='dsfsdf')
        db.session.add(article)
        db.session.commit()
        return 'Hello World!'
    
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    相关文章

      网友评论

        本文标题:flask-migrate动态迁移数据库

        本文链接:https://www.haomeiwen.com/subject/nsbgrqtx.html