zoukankan      html  css  js  c++  java
  • Flask 系列之 SQLAlchemy

    SQLAlchemy 是一种 ORM 框架,通过使用它,可以大大简化我们对数据库的操作,不用再写各种复杂的 sql语句 了。

    说明

    • 操作系统:Windows 10
    • Python 版本:3.7x
    • 虚拟环境管理器:virtualenv
    • 代码编辑器:VS Code

    实验目标

    实现网站与 mysql 数据库的连接和 CRUD 操作。

    MYSQL 的安装与配置

    打开 Ubuntu 16.04 的 bash 界面,执行下述操作

    # 安装
    sudo apt update && sudo apt install mysql-server mysql-client
    sudo service mysql status
    
    # 配置安全性
    sudo mysql_secure_installation
    sudo mysqladmin -p -u root version
    
    # 查看状态
    sudo service mysql status
    sudo service mysql start
    sudo service mysql stop
    
    # 设置字符编码
    sudo vim /etc/mysql/conf.d/mysql.cnf
    
    # 修改如下:
    [mysql]
    no-auto-rehash
    default-character-set=utf8
    [mysqld]
    socket = /var/run/mysqld.sock
    port =3306
    character-set-server=utf8  # 必须设置,否则会导致无法插入中文数据
    
    # 重启服务
    sudo service mysql restart
    

    mysql 常用用法

    # 进入 mysql
    mysql -u root -p
    
    # 查看当前字符编码
    show variables like 'character%';
    
    # 创建数据库 db_name
    create database db_name charset=utf8;
    
    # 显示以存在的所有数据库
    show databases;
    
    # 指定数据库 db_name
    use db_name;
    
    # 创建数据库表
    create table table_name;
    
    # 查看表信息
    desc tablename;
    
    # 删除 数据库 db_name
    drop database db_name;
    
    # 退出
    exit;
    

    使用 SQLAlchemy

    首先进入 mysql 的控制台界面,创建我们需要使用的数据库

    sudo mysql -u root -p
    create database todo;
    use todo;
    

    安装 flask-sqlalchemy

    pip install pymysql
    pip install flask-sqlalchemy
    

    todolist 目录下创建 config.py 文件,示例代码如下所示:

    import os
    
    basedir = os.path.abspath(os.path.dirname(__file__))
    
    
    class Config(object):
        SQLALCHEMY_DATABASE_URI = os.environ.get(
            'SQLALCHEMY_DATABASE_URI') or 'mysql+pymysql://root:mysql@127.0.0.1:3306/todo'
        SQLALCHEMY_TRACK_MODIFICATIONS = False
    

    修改 todolistapp\__init__.py,示例代码如下所示:

    from flask import Flask, render_template
    from flask_sqlalchemy import SQLAlchemy
    from config import Config
    
    app = Flask(__name__)
    app.config.from_object(Config)
    db = SQLAlchemy(app)
    
    
    @app.route('/')
    @app.route('/index')
    def index():
        title = 'Home'
        greet = 'Hello World'
        return render_template('index.html', title=title, greet=greet)
    

    todolist 目录下创建 models.py 文件,示例代码如下所示:

    from app import db
    from datetime import datetime
    
    
    class User(db.Model):
        __tablename__ = 'users'
        # __table_args__ = {"useexisting": True}
    
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(20), nullable=False, unique=True)
        email = db.Column(db.String(120), nullable=False, unique=True)
        pwd = db.Column(db.String(120), nullable=False)
    
        things = db.relationship('Thing', backref='User', lazy='dynamic')
    
        def __repr__(self):
            return "<User %r>" % self.name
    
    
    class Thing(db.Model):
        __tablename__ = 'things'
        # __table_args__ = {"useexisting": True}
    
        id = db.Column(db.Integer, primary_key=True)
        user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
        title = db.Column(db.String(20), nullable=False)
        text = db.Column(db.Text, nullable=False)
        add_date = db.Column(db.DateTime, default=datetime.now)
    
        def __repr__(self):
            return "<Todo %r>" % self.id
    

    修改 todolistmanage.py,示例代码如下所示:

    from app import app, db
    from models import User, Thing
    from werkzeug.security import generate_password_hash
    
    if __name__ == "__main__":
        db.drop_all()
        db.create_all()
    
        pwd = generate_password_hash('123456789')
        u1 = User(name='admin', email='admin@outlook.com', pwd=pwd)
        db.session.add(u1)
        db.session.commit()
    
        t1 = Thing(user_id=1, title='hello world', text='welcome to my hippiedom.')
        db.session.add(t1)
        db.session.commit()
    
        u2 = User.query.get(1)
        print(u2)
    
        app.run(debug=True, host='0.0.0.0', port=5000)
    

    此时,执行 python manage.py,若程序无数据库相关的错误信息,则表明数据库中相应表已经创建成功,我们可以在 mysql 的 shell 窗口进行查看。

    SQLAlchemy常用操作:

        查询所有用户数据
        User.query.all()
    
        查询有多少个用户
        User.query.count()
    
        查询第1个用户
        User.query.first()
        User.query.get(1)   # 根据id查询
    
        查询id为4的用户[3种方式]
        User.query.get(4)
        User.query.filter_by(id=4).all()   # 简单查询  使用关键字实参的形式来设置字段名
        User.query.filter(User.id == 4).all()  # 复杂查询  使用恒等式等其他形式来设置条件
    
        查询名字结尾字符为g的所有用户[开始 / 包含]
        User.query.filter(User.name.endswith("g")).all()
        User.query.filter(User.name.startswith("w")).all()
        User.query.filter(User.name.contains("n")).all()
        User.query.filter(User.name.like("%n%g")).all()  模糊查询
    
        查询名字和邮箱都以li开头的所有用户[2种方式]
        User.query.filter(User.name.startswith("li"), User.email.startswith("li")).all()
    
        from sqlalchemy import and_
        User.query.filter(and_(User.name.startswith("li"), User.email.startswith("li"))).all()
    
        查询age是25 或者 `email`以`itheima.com`结尾的所有用户
        from sqlalchemy import or_
        User.query.filter(or_(User.age == 25, User.email.endswith("itheima.com"))).all()
    
        查询名字不等于wang的所有用户[2种方式]
        from sqlalchemy import not_
        User.query.filter(not_(User.name == "wang")).all()
        User.query.filter(User.name != "wang").all()
    
        查询id为[1, 3, 5, 7, 9]的用户
        User.query.filter(User.id.in_([1, 3, 5, 7, 9])).all()
    
        所有用户先按年龄从小到大, 再按id从大到小排序, 取前5个
        User.query.order_by(User.age, User.id.desc()).limit(5).all()
    
        分页查询, 每页3个, 查询第2页的数据
        pn = User.query.paginate(2, 3)
        pn.items  获取该页的数据     pn.page   获取当前的页码     pn.pages  获取总页数
    

    常用 API 参考

    # 基本使用
    db.drop_all()
    db.create_all()
    db.session.add(对象)
    db.session.commit()
    
    # 数据类型
    db.Integer:整型
    db.String (size):字符串,size 为最大长度,比如 db.String(20)
    db.Text:长文本
    db.DateTime:时间日期,Python datetime 对象
    db.Float:浮点数
    db.Boolean:布尔值
    
    # 过滤方法
    格式:<模型类>.query.<过滤方法(可选)>.<查询方法>
    filter():使用指定的规则过滤记录,返回新产生的查询对象
    filter_by():使用指定规则过滤记录(以关键字表达式的形式),返回新产生的查询对象
    order_by():根据指定条件对记录进行排序,返回新产生的查询对象
    group_by():根据指定条件对记录进行分组,返回新产生的查询对象
    
    # 查询方法
    all():返回包含所有查询记录的列表
    first():返回查询的第一条记录,如果未找到,则返回None
    get(id):传入主键值作为参数,返回指定主键值的记录,如果未找到,则返回None
    count():返回查询结果的数量
    first_or_404():返回查询的第一条记录,如果未找到,则返回404错误响应
    get_or_404(id):传入主键值作为参数,返回指定主键值的记录,如果未找到,则返回404错误响应
    paginate():返回一个Pagination对象,可以对记录进行分页处理
    

    参考

  • 相关阅读:
    基于摸板匹配的目標跟蹤算法
    spoj 2713 Can you answer these queries IV
    zoj 3633 Alice's present
    hdu 3642 Get The Treasury
    poj 1195 Mobile phones
    poj 2760 End of Windless Days
    zoj 3540 Adding New Machine
    spoj 1716 Can you answer these queries III
    spoj 1043 Can you answer these queries I
    spoj 2916 Can you answer these queries V
  • 原文地址:https://www.cnblogs.com/hippieZhou/p/10273383.html
Copyright © 2011-2022 走看看