• flask(三)之Flask-SQLAlchemy


    01-介绍

    Flask-SQLAlchemy是一个Flask扩展,简化了在Flask应用中使用SQLAlchemy的操作。SQLAlchemy提供了高层ORM,也提供了使用数据库原生SQL的低层功能。

    # 安装
    
    pip install flask-sqlalchemy

    在Flask-SQLAlchemy中,数据库使用URL指定。

    应用使用的数据库URL必须保存到Flask配置对象的 SQLALCHEMY_DATABASE_URI 键中。

    建议把 SQLALCHEMY_TRACK_MODIFICATIONS 键 设为 False,以便在不需要跟踪对象变化时降低内存消耗。

    02-数据库的连接

    from flask import Flask
    # 1.导入
    from flask_sqlalchemy import SQLAlchemy
    
    app = Flask(__name__)
    #2.定义要连接的数据库
    DB_URI = "mysql+pymysql://root:123456@127.0.0.1:3306/learn_sqlalchemy?charset=utf8"
    #3.添加到到配置中
    app.config['SQLALCHEMY_DATABASE_URI'] = DB_URI
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] =False
    # 4.实例化一个对象,将app传进去
    db = SQLAlchemy(app)
    
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    
    if __name__ == '__main__':
        app.run()

     03-定义模型

    class User(db.Model):
        __tablename__ = 'user'
        id = db.Column(db.Integer,primary_key=True,autoincrement=True)
        username = db.Column(db.String(50),nullable=False)
    
      def __repr__(self):
        return self.username
    
    
    
    class Article(db.Model):
        __tablename__ = "article"
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        title = db.Column(db.String(50), nullable=False)
        uid = db.Column(db.Integer,db.ForeignKey("user.id"))
        author = db.relationship("User",backref='article')
        
        def __repr__(self):
        return self.title

    __tablename__ 定义在数据库中的表名。

    04-一对多的关系

    例:一个角色对应多个用户:

    class Role(db.Model):
        # ...
        users = db.relationship('User', backref='role')
    
    class User(db.Model):
        # ...
        role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

    db.relationship()中的第一个参数指的是这个关系的另一端是哪个模型,backref参数向User模型添加一个role属性,从而定义反向关系。

     

    05-操作

    # 创建表
    db.create_all()
    
    # 删除表
    db.drop_all()
    
    # 插入行
    admin_role = Role(name='admin')
    user_role= User(username='hyp', role=admin_role)
    
    # 对数据库的改动童年过数据库会话管理,在Flask-SQLAlchemy中,会话由 db.session 表示。在写入数据库之前,要先添加到会话中:
    db.session.add(admin_role)
    db.session.add(user_role)
    # 或者
    db.session.add_all([admin_role, user_role])
    
    # 为了写入数据库,要调用 commit()方法提交会话:
    db.session.commit()
    
    # 数据库回话能保证数据库的一致性。数据库回话也可以回滚,调用 db.session.rollback()
    
    # 修改行
    admin_role.name= 'lcy'
    db.session.add(admin_role)
    db.session.commit()
    
    # 删除行
    db.session.delete(admin_role)
    db.session.commit()  # 注意:删除、更新和插入一样,提交数据会话才执行。
    
    # 查询行
    # 每个模型类都提供了query对象。
    Role.query.all()
    Role.query.filter_by(role=user_role).all()
    
    # 查看生成的原生SQL查询语句,只需要把query对象转换成字符串:
    str(User.query.filter_by(role=user_role))
    
    # first()方法 只返回第一个结果
    user_role = Role.query.filter_by(name='User').first()

    06-集成Python Shell

    若想把对象添加到入列表中,必须使用 app.shell_context_processor 装饰器创建并注册一个shell上下文处理器。

    @app.shell_context_processor
    def make_shell_context():
        return dict(db=db, User=User, Role=Role)

    这个shell上下文处理器函数返回一个字典,包含数据库实例和模型。

    07-使用 Flask-Migrate实现数据库迁移

    Flask应用还可以使用Flask-Migrate扩展,是对Alembic的轻量级包装。

    # 安装
    
    pip install flask-migrate

    manage.py

    from flask_script import Manager
    from flask_migrate_demo import app
    from exts import db
    import models   #这个一定要导入
    from flask_migrate import Migrate,MigrateCommand
    
    manager = Manager(app)
    Migrate(app,db)
    manager.add_command("db",MigrateCommand)   #把所有命令放到db里面
    
    if __name__ == '__main__':
        manager.run()

    初始化

    python manage.py db init

    创建迁移脚本

    python manage.py db migrate -m '第一次提交'

    生成到数据库

    python manage.py db upgrade

    08-alembic数据迁移工具

    alembic是用来做ORM模型与数据库的迁移与映射。alembic使用方式跟git有点类似,表现在两个方面,第一个,alemibi的所有命令都是以alembic开头;

    第二,alembic的迁移文件也是通过版本进行控制的。

    # 安装
    
    pip install alembic

    使用:

    # model.py
    
    from sqlalchemy import Column,Integer,String,create_engine
    from  sqlalchemy.ext.declarative import declarative_base
    
    DB_URI = "mysql+pymysql://root:123456@127.0.0.1:3306/alembic_demo?charset=utf8"
    
    engine = create_engine(DB_URI)
    
    Base = declarative_base(engine)
    
    class User(Base):
        __tablename__ = 'user'
        id = Column(Integer,primary_key=True,autoincrement=True)
        username = Column(String(50),nullable=False)

    在终端初始化,创建一个仓库

    alembic init learn_alembic

    修改配置文件,指定连接的数据库

    # alembic.ini
    
    sqlalchemy.url = mysql+pymysql://root:123456@127.0.0.1:3306/alembic_demo?charset=utf8

    将models所在的目录路径添加到env.py,并指定target_metadata

    import sys,os
    # 1.__file__:当前文件(env.py)
    #2.os.path.dirname(__file__):获取当前文件的目录
    #3.os.path.dirname(os.path.dirname(__file__)):获取当前文件目录的上一级目录
    #4.sys.path: python寻找导入的包的所有路径
    sys.path.append(os.path.dirname(os.path.dirname(__file__)))
    import models
    
    
    target_metadata = models.Base.metadata

    生成迁移脚本

    alembic revision --autogenerate -m "第一次提交"

    将生成的迁移脚本映射到数据库中

    alembic upgrade head

    以后如果想要添加或修改模型,重复最后两步即可。

    常用命令:

    init:创建一个alembic仓库
    rebision:创建一个新的版本文件
    --autogenerate:自动将当前模型的修改,生成迁移脚本
    -m:本次迁移做了哪些修改
    upgrade:将指定版本的迁移文件映射到数据库中,会执行版本文件中的upgrade函数
    head:代表当前的迁移脚本的版本号
    downgrade:会执行指定版本的迁移文件中的downgrade函数
    heads:展示当前可用的heads脚本文件
    history:列出所有的迁移版本及其信息
    current:展示当前数据库中的版本号
     经典错误
    
    1.FAILED:Target databases is not up to date.
    
       原因:主要是heads和current不相同。current落后于heads的版本
    
       解决办法:将current移动到head上。alembic upgrade head
    
    2.FAILED:Can't locate revision identified by 'xxxxxxx'
    
       原因:数据库中存的版本号不在迁移脚本文件中
    
       解决办法:删除数据的alembic_version表中的数据,重新执行alembic upgrade head

    用alembic工具:数据库中会自动生成一张表alembic_version

    在数据库中可以查看当前的版本号

    在cmd终端也可以通过current命令查看

    alembic current

    Flask-SQLAlchemy下使用alembic:

    1. config.py

    DB_URI = "mysql+pymysql://root:123456@127.0.0.1:3306/flask_alembic_demo?charset=utf8"
    
    SQLALCHEMY_DATABASE_URI = DB_URI

    (2)flask_alembic_demo.py

    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    import config
    
    app = Flask(__name__)
    app.config.from_object(config)
    
    db = SQLAlchemy(app)
    
    class User(db.Model):
        __tablename__ = 'user'
        id = db.Column(db.Integer,primary_key=True,autoincrement=True)
        username = db.Column(db.String(50),nullable=False)
      
    
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    
    if __name__ == '__main__':
        app.run()

    (3)初始化

    alembic init alembic

    (4)alembic.ini

    sqlalchemy.url = mysql+pymysql://root:123456@127.0.0.1:3306/flask_alembic_demo?charset=utf8

    (5)env.py

    import sys,os
    sys.path.append(os.path.dirname(os.path.dirname(__file__)))
    import flask_alembic_demo
    
    # 用的是db.Model
    target_metadata = flask_alembic_demo.db.Model.metadata

    (6)生成迁移脚本

    alembic revision --autogenerate -m "first commit"

    (7)upgrade到数据库

    alembic upgrade head

    (8)添加字段

    假入想添加一个字段age

    class User(db.Model):
        __tablename__ = 'user'
        id = db.Column(db.Integer,primary_key=True,autoincrement=True)
        username = db.Column(db.String(50),nullable=False)
        age = db.Column(db.Integer) 

    重复步骤即可

    alembic revision --autogenerate -m "add column age"
    
    alembic upgrade head
  • 相关阅读:
    n个元素进栈,有几种出栈方式
    The following IP can be used to access Google website
    一个未排序整数数组,有正负数,重新排列使负数排在正数前面,并且要求不改变原来的 相对顺序 比如: input: 1,7,-5,9,-12,15 ans: -5,-12,1,7,9,15 要求时间复杂度O(N),空间O(1) 。
    当今世界最受人们重视的十大经典算法
    指针
    变量作用域和生存期
    一篇文章搞清spark内存管理
    Spark的Shuffle是怎么回事
    一篇文章搞清spark任务如何执行
    scala这写的都是啥?一篇文章搞清柯里化
  • 原文地址:https://www.cnblogs.com/pgxpython/p/10422840.html
Copyright © 2020-2023  润新知