• Python Flask学习笔记之数据库


    Flask中的数据库

    Flask本身不支持数据库,对使用的数据库插件自由选择。

    数据库被划分为两大类,遵循关系模型的一类是关系数据库,另外的则是非关系数据库,简称NoSQL,表现在它们不支持流行的关系查询语言SQL。

    使用Flask-SQLAlchemy管理数据库

    Flask-SQLAlchemy是一个Flask扩展,简化了在Flask程序中使用SQLAlchemy的操作。SQLAlchemy是一个很强大的关系型数据库框架,支持包含MySQL、PostgreSQL和SQLite在内的很多数据库软件。

    • 安装
    pip install flask-sqlalchemy
    
    • 常见数据库URL格式
    mysql   mysql://username:password@hostname/database
    postgres    postgresql://username:password@hostname/database
    sqlite  sqlite:///absolute/path/to/database
    
    • 配置数据库
    # config.py
    import os
    basedir = os.path.abspath(os.path.dirname(__file__))
    
    class Config(object):
       
        SECRET_KEY = os.environ.get('SECRET_KEY') or 'marksecret'
    
        SQLALCHEMY_DATABASE_URI =  'mysql://root:root@localhost/flask'
        SQLALCHEMY_TRACk_MODIFICATIONS = False
        SQLALCHEMY_COMMIT_TEARDOWN = True
    
    # __init__.py变更后
    from flask import Flask
    from config import Config
    from flask_sqlalchemy import SQLAlchemy
    from flask_migrate import Migrate
    
    app = Flask(__name__)
    app.config.from_object(Config)
    db = SQLAlchemy(app)
    migrate = Migrate(app,db)
    
    from app import routes,models
    

    模型

    定义数据库中一张表及其字段的类,通常叫做数据模型。ORM(SQLAlchemy)会将类的实例关联到数据库表中的数据行,并翻译相关操作。

    mysql> desc user;
    +---------------+--------------+------+-----+---------+-------+
    | Field         | Type         | Null | Key | Default | Extra |
    +---------------+--------------+------+-----+---------+-------+
    | id            | int(11)      | NO   | PRI | NULL    |       |
    | username      | varchar(64)  | YES  |     | NULL    |       |
    | email         | varchar(120) | YES  |     | NULL    |       |
    | password_hash | varchar(128) | YES  |     | NULL    |       |
    +---------------+--------------+------+-----+---------+-------+
    

    代码实现

    # models.py
    from app import db
    
    class User(db.Model):
        
        id =db.Column(db.String(64), primary_key=True,index=True, unique=True)
        username = db.Column(db.String(64), index=True, unique=True)
        email = db.Column(db.String(120), index=True, unique=True)
        password_hash = db.Column(db.String(128))
    
        def __repr__(self):
            return '<User {}>'.format(self.username)
    
    

    测试

    >>> from app.models import User
    >>> u = User(username='mark',email='test@xx.com')
    >>> u
    <User mark>
    >>> 
    

    关系

    关系数据库使用关系把不同表中的行联系起来。一旦建立了关系,数据库就可以在查询中展示它。

    roles表存储所有可用的用户角色,每个角色使用一个唯一的id值(即表的主键)进行标识。users表除了id主键之外,role_id是外键,引用角色的id,通过这种方式为每个用户指定角色。

    示例代码

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

    关系使用users表中的外键连接了两行。添加到user模型中的role_id被定义为外键,就是这个外键建立起了关系。传给db.ForeignKey()的参数role_id表明,这列的值是roles表中的id值

    db.relationship()第一个参数表明这个关系的另一端是哪个模型。backref参数向user模型中添加了一个role属性,从而定义反向关系。这一属性可替代role_id访问role模型,此时获取的是模型对象,而不是外键的值。

    数据库操作

    >>> from app import db
    >>> from app.models import User
    # 增加用户mark
    >>> u = User(id=1,username='mark', email='mark@qq.com')
    >>> u
    >>> db.session.add(u)
    >>> db.session.commit()
    
    >>> user = User.query.all()
    >>> user
    [<User mark>]
    # 增加用户test
    >>> u2 = User(id=2,username='test', email='test@qq.com')
    >>> db.session.add(u2)
    >>> db.session.commit()
    >>> print user.id
    2
    >>> print user.email
    test@qq.com
    
    >>> u2.username
    u'test'
    >>> u2.username = 'mark2'
    >>> db.session.add(u2)
    >>> db.session.commit()
    >>> a=User.query.all()
    >>> a
    [<User mark>, <User mark2>]
    >>> 
    
    >>> db.session.delete(u2)
    >>> db.session.commit()
    >>> a=User.query.all()
    >>> a
    [<User mark>]
    >>> 
    

    python shell(shell上下文)

    开发应用时,需要经常在Python shell中测试,所以每次重复导入会变得很繁琐。flask shell命令是flask命令集中的另一个非常有用的工具。

    # manage.py
    from app import app, db
    from app.models import User, Post
    
    @app.shell_context_processor
    def make_shell_context():
        return {'db': db, 'User': User, 'Post': Post}
    

    flask shell的绝妙之处不在于它预先导入了app,而是你可以配置一个“shell上下文”,也就是可以预先导入一份对象列表。

    (env) mark@mark-Pc:~/flask$ flask shell
    >>> User
    <class 'app.models.User'>
    >>> db
    <SQLAlchemy engine=mysql://root:***@localhost:3306/flask?charset=utf8>
    >>> app
    <Flask 'app'>
    

    数据库迁移

    • 安装插件
    pip install flask-migrate
    
    • 创建迁移仓库
    flask db init
    
    • 创建迁移脚本
    flask db migrate -m "user table"
    
    • 更新数据库
    flask db upgrade
    
  • 相关阅读:
    【原创】自己动手写工具----签到器[Beta 1.0]
    都2020了,还不好好学学泛型?
    ThreadLocal = 本地线程?
    从BWM生产学习工厂模式
    你还在用BeanUtils进行对象属性拷贝?
    JDK 1.8 之 Map.merge()
    Spring Boot认证:整合Jwt
    以商品超卖为例讲解Redis分布式锁
    如何从 if-else 的参数校验中解放出来?
    分布式全局唯一ID生成策略​
  • 原文地址:https://www.cnblogs.com/mark-zh/p/11290340.html
Copyright © 2020-2023  润新知