flask-mysql的连接以及增删改查数据-学习笔记

flask中mysql的连接以及增删改查数据

flask中连接mysql需要安装进行一下几个步骤:

一、需要安装两个模块
首先,创建一个falsk项目
需要安装pymysql与flask-sqlalchem模块,可通过pip命令进行安装,也可在pycharm的界面进行安装,这里不做演示

二、配置数据库连接
在flask项目下创建一个settings.py文件,并配置数据库的相关参数

settings.py

DEBUG = True 		# 当处于debug状态时,每修改一次flask中的代码,都会中新reload一次flask项目
    # mysql(数据库软件) + pymsql(连接数据库的模块)://数据库用户:密码@ip:端口/库名
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://用户名:密码@IP:端口/数据库名'
SQLALCHEMY_TRACK_MODIFICATIONS = False      # 消除警告信息
SQLALCHEMY_ECHO = True

创建一个app目录,为了便于存放管理路由。当项目中路由数过多,全部放在app.py文件不便于管理,最好app.py中只存放启动代码,不同的路由分开存放。我们创建一个app目录就是为了保存管理路由。在app目录下再创建一个users目录,用户管理用户功能的路由。
在users目录中创建一个module.py的文件,文件主要是用于连接数据库,定义mysql数据的表

# 创建一个映射对象
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
# ORM   类------表
# 类对象  ------  表中的记录
from datetime import datetime



class User(db.Model):	# 继承db中的Model,这里的类名也是表名
    """
    # db.Column(类型, 约束) 映射表中的列
    # 类型:             相当与mysql中表字段类型
        db.Integer      int
        db.String(12)   vachar(15)
        db.DateTime     datetime

    """
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(20), nullable=False)	 # nullable 表示字段能不能为空
    password = db.Column(db.String(64), nullable=False)
    phone = db.Column(db.String(11), unique=True)
    email = db.Column(db.String(30), nullable=False)  # nullable 表示字段不能为空
    redatatime = db.Column(db.DateTime, default=datetime.now)
    isdelete = db.Column(db.Boolean, default=False)         # 用于标志是否删除用户

    def __str__(self):

        return self.username

在users目录下创建一个view.py的管理路由试图的文件

import hashlib
from operator import or_, and_, not_

from flask import Blueprint, url_for, request, render_template, redirect


from apps.users.module import Easyops, User
from ext import db

user_bp = Blueprint('user', __name__)

# 用户首页,展示
@user_bp.route('/')
def user_center():
    users = User.query.filter(User.isdelete == False).all()
    # users = User.query.all()        # 相当于slect * from 表
    print(users)                    # 返回的为一个列表,列表中存放的为用户对象
    # print(url_for('/'))       # 反向解析,通过视图找到url,需要先指定: url_for(蓝图.视图函数)

    return render_template('user/center.html', users=users)
#print(user_bp.url_values_defaults)

# 用户注册
@user_bp.route('/register', methods= ['GET', 'POST'])
def register():
    if request.method == "POST":
        username = request.form.get('username')
        email = request.form.get('email')
        password = request.form.get('password')
        reapssword = request.form.get('repassword')
        phone = request.form.get('phone')
        if password == reapssword:
            # 与模型结合,完成数据库的添加
            # 1、找到模型类并创建对象
            user = User()   # 这里需要导入User类,可看import
            # 2、为对象赋值
            user.username = username
            user.password = hashlib.sha256(password.encode('utf-8')).hexdigest()
            user.phone = phone
            user.email = email
            # 添加
            # 3、将user对象添加到session中,类似于缓存
            db.session.add(user)
            # 4、提交数据部分
            db.session.commit()     # commit成功则表示数据插入成功
            return redirect('/')
        else:
            return "两次密码不一致"
    return  render_template('user/register.html')


# 用户登录
@user_bp.route('/login', methods=["GET", "POST"])
def login():
    if request.method == "POST":
        username = request.form.get('username')
        password = request.form.get('password')
        # 关键  select * from user where username = 'xxxx'
        nex_password = hashlib.sha256(password.encode('utf-8')).hexdigest()         # 生成新的加密密码
        # 查询    filter_by相当于sql中的where,返回值为一个列表结构,可能查询到多条数据
        # filter_by(xxxx='xxx').first()  代表从列表中取出第一条数据
        # filter_by(xxxx='xxx').last()  代表从列表中取出第一条数据

        users_info = User.query.filter_by(username=username)        # 这里前面的username是user表中的表字段,后面的为对应的值
        print(users_info)
        for user in users_info:
            if user.password == nex_password:
                return '用户登录成功'
        else:
            return render_template('user/login.html', msg='用户名或者密码有误!')
    return render_template('user/login.html')


# 查找
@user_bp.route('/search')
def search():
    keyword = request.args.get('search')
    # 查询
    user_info = User.query.filter(or_(User.username.contains(keyword), User.phone.contains(keyword))).all()         # 这是查询到的用户数据
    return render_template('user/center.html', users=user_info)



# 删除用户
@user_bp.route('/delete')
def delete():
    # 从请求中获取到传参id的值
    id = request.args.get('id')
    # 通过id找到对应的用户,因为id是主键,所以get
    id_user = User.query.get(id)
    # # 进行逻辑删除
    ##############################
    # 逻辑删除
    # id_user.isdelete = True
    # db.session.commit()
    ######################################
    # 物理删除
    db.session.delete(id_user)      # 将对象放到缓存中
    db.session.commit()             # 提交删除
    return redirect(url_for('user.user_center'))


@user_bp.route('/test')
def test():
    username = request.args.get('username')
    users_info = User.query.filter_by(username=username).first()
    print(users_info.username, users_info.phone)
    return 'test'


# 检索
@user_bp.route('/select')
def select():
    user_info = User.query.get(0)       # 根据主键查询用户,使用get(主键值),返回的是一个用户对象
    # lu_info = User.query.filter(User.username == 'lu').all()        # all()返回一个列表 filer()返回第一条数据
    lu_info = User.query.filter(User.username.startswith('lu')).all()   # 这里是是以username字段中以lu开头的用户,startswith表示以xx开头
    lu_info_end = User.query.filter(User.username.endswith('lu')).all() # 这里是以lu结尾的用户
    lu_info_cen = User.query.filter(User.username.contains('lu')).all()  # 包含,这里是以usernmae中包含lu的用户
    select_info = User.query.filter(or_(User.username.like('l%'), User.username.contains('u'))).all()       # 这里是表示查询中表示or
    and_info = User.query.filter(and_(User.username.contains('l'), User.redatatime < '2021-03-07 20:35')).all()     # 这里是查询表示and
    #not_info = User.query.filter(not_(User.username.contains('u'))).all()
    user_list = User.query.filter(User.phone.in_(['110', '120'])).all()
    # 排序
    users_all = User.query.filter(User.username.contains('f')).order_by('redatatime').all()     #   这里表示先查询,然后将查询出来的数据通过redatatime字段进行排序,默认惊醒升序排序
    user_id = User.query.order_by(User.redatatime).all()                # 这里是通过User的redatatime对所有的进行排序,默认进行升序
    users_id = User.query.order_by(-User.redatatime).all()              # 进行降序,在前面加-
    # limit
    limit_info = User.query.order_by(User.id).limit(2).all()           # 这里是将查询出来的值,limit(2获取前两条记录
    limit_info1 = User.query.offset(2).limit(2).all()                   # offset(2)表示跳过前两条,limit(2)再获取两条记录
    return render_template('user/select.html', user_info=user_info, lu_info=lu_info,lu_info_end=lu_info_end,lu_info_cen=lu_info_cen, select_info=select_info, and_info=and_info, user_list=user_list
                           ,users_all=users_all,user_id=user_id,users_id=users_id,limit_info=limit_info, limit_info1=limit_info1)

@user_bp.route('/update', endpoint='update', methods=["GET", "POST"])
def update():
    if request.method == "POST":
        username = request.form.get('username')
        phone = request.form.get('phone')
        id = request.form.get('id')
        # 通过主键id找到对应的用户
        user_info = User.query.get(id)
        # 修改用户信息
        user_info.phone = phone
        user_info.username = username
        db.session.commit()
        return redirect(url_for('user.user_center'))

    else:
        user_id = request.args.get('id')
        user = User.query.get(user_id)
        return render_template('user/update.html', user=user)

在app目录下的__init__.py

from flask import Flask

import settings
from apps.users.module import db
from apps.users.view import user_bp

def create_app():
    app = Flask(__name__, template_folder='../templates', static_folder='../static')    # 定义模版templates的路径和static路径
    app.config.from_object(settings.DevelopmentConfig)
    db.init_app(app)    # 将db与app进行关联

    app.register_blueprint(user_bp)     # 注册蓝图1
    return app

app.py文件

# encoding: utf-8
from flask_migrate import Migrate,MigrateCommand
from flask_script import Manager
from apps import create_app
# from ext import db
from apps.users.module import Easyops, UserInfo, User, db

app = create_app()

manager = Manager(app=app)      # app需要定义,使用先定义的app
#  /Users/julie-zhou/flaskProject/bin/python app.py runserver
# 还可以在后面接参数,通过--help查看

# 命令工具
migrate = Migrate(app=app, db=db)
manager.add_command('db', MigrateCommand)

# 自定义命令
@manager.command
def init():
    print('初始化!')

if __name__ == '__main__':
    manager.run()

三、运行flask项目
在第一次连接数据库时,应当按照一下步骤来进行
注意:init命令只有在第一次连接数据库新建表的时候使用,当修改表时只需要使用migrate和upgrade命令

在终端使用命令:db
        python app.py  db init      # 执行命令后会在项目文件夹中产生一个migrations文件夹,一个项目只需要init一次
    再执行命令:db
        python app.py  db migrate   # 会在migrations文件夹下的versions文件夹下生成一个xxxx.py的文件,只要对模型做了任何操作都需要进行migrate
    再次执行命令:db
        python app.py  db upgrade   # 就会在mysql对应的数据库中创建表

数据库的连接总结

########################
#       连接数据库       #
########################
1、安装模块
    需要装两个模块:pymysql、flask-sqlalchem、
    pymysql:    连接数据库
    sqlalchem:  ORM映射关系
    flask-sqlalchem 基于sqlalchem,做了提升

2、配置数据库的连接路径
    配置文件setting.py中配置数据库连接
    # mysql(数据库软件) + pymsql(连接数据库的模块)://数据库用户:密码@ip:端口/库名
        SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://easyops:easyops@47.107.229.100:3306/easyops'

3、创建ext包
    在__init__.py中添加
    from flask_sqlalchemy import SQLAlchemy
    db = SQLAlchemy()

4、在apps包
    在__init__.py的create_app函数中
    from ext import db
    db.init_app(app)    # 将db与app进行关联

5、创建模型:
    创建modles.py,这个文件中的每一个类就是定义一张表
    模型就是类
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        username = db.Column(db.String(15), nullable=False)
        password = db.Column(db.String(12), nullable=False)
        phone = db.Column(db.String(11), unique=True)
        redatatime = db.Column(db.DateTime, default=datetime.now)
6、使用命令
    *******************************
    在app.py中导入模型:from apps.users.modles import Easyops
    在终端使用命令:db
        python app.py  db init      # 执行命令后会在项目文件夹中产生一个migrations文件夹,一个项目只需要init一次
    再执行命令:db
        python app.py  db migrate   # 会在migrations文件夹下的versions文件夹下生成一个xxxx.py的文件,只要对模型做了任何操作都需要进行migrate
    再次执行命令:db
        python app.py  db upgrade   # 就会在mysql对应的数据库中创建表

7、数据的插入
    数据的插入可以通过flask的request获取到参数,通过之前创建的连接数据库的类(modeule中的Easyops类)创建连接对象
    而后通过db(ext下的__init__中定义)的session.add和session.commit将数据插入到数据库



#####################################
加密方式:md5、sha1、sha256、sha512
import hashlib
在hashlib中有很多的加密方式


######################################
1、查询
# 模型类为module.py文件中对应的类名,每个类就是一张表
查询所有:   模型类.query.all()         # 相当于select * from 表名
有条件的查询:
    模型类.query.fillter_by(字段名=)     # 相当于select * from 表名 where xxx=xxx     返回值为一个列表
    模型类.query.fillter_by(字段名=).first()     # 这是获取条件查询的到第一条记录,相当于  select * from 表名 where xxx=xxx limit 1
select * from table_name where xxx1 > xx and xxx2=xxxx
select * from table_name where xxx1 like 'xxx%'
    模型类.query.filter()  里面是布尔类型 模型类.query.filter(模型名.字段名==)
    模型类.query.filter_by()  里面是一个等值 模型类.query.filter_by(字段名=)

*************  模型类.query.filter() ****************
1、模型类.query.filter().all()      返回一个列表
2、模型类.query.filter().first()    返回一个对象,默认返回第一个对象

#####
字符串的匹配:
    lu_info = User.query.filter(User.username.startswith('lu')).all()   # 这里是是以username字段中以lu开头的用户,startswith表示以xx开头
    lu_info_end = User.query.filter(User.username.endswith('lu')).all() # 这里是以lu结尾的用户
    lu_info_cen = User.query.filter(User.username.contains('lu')).all()  # 包含,这里是以usernmae中包含lu的用户
    user_list = User.query.filter(User.phone.in_(['110', '120'])).all()     # 这是user表中phone字段的值在列表中的
    user_list = User.query.filter(User.phone == "xxxx").all()               # 这是等于的

整形或者日期的匹配:
    __lt__(小于)、__gt__(大于)、__ge__(大于等于)、__le__(小于等于) between(x1,x2) (这是范围检索)
    也可以:<>>=<=、
    使用方法与上面一致,如:
    user_list = User.query.filter(User.phone < "xxxx").all()
    user_list = User.query.filter(User.phone.__lt__('xxxx')).all()      # 这两个都是表示phone字段小于xxx的
    user_age = User.query.filter(User.age.between('x1', 'x2')).all()    # 这是查询age字段的值在x1到x2之间的

多条件查询:
    and_ or_ not_
    from operator import or_, and_, not_
    select_info = User.query.filter(or_(User.username.like('l%'), User.username.contains('u'))).all()   # 这里是查询或者,为包含u或者名字以l开头
    表示:sql中的or查询
    and_info = User.query.filter(and_(User.username.contains('l'), User.redatatime < '2021-03-07 20:35')).all()     # 这里是查询表示and
    表示:sql中的and查询,中间的符号也可以用 __lt__(小于)、__gt__(大于)、__ge__(大于等于)、__le__(小于等于)
    使用:User.redatatime.__lt__('2021-03-07 20:35')   这里是表示User中redatatime字段的值小于('2021-03-07 20:35')

排序:
    order_by()
    1、可以直接是字符串:'字段名',但是不能降序,如:order_by('字段名')
    2、通过字段名: 模型.字段名     如:order_by(模型.字段名)默认升序  order_by(-模型.字段名)   降序
    users_all = User.query.filter(User.username.contains('f')).order_by('redatatime').all()     #   这里表示先查询,然后将查询出来的数据通过redatatime字段进行排序,默认惊醒升序排序
    user_id = User.query.order_by(User.redatatime).all()                # 这里是通过User的redatatime对所有的进行排序,默认进行升序
    users_id = User.query.order_by(-User.redatatime).all()              # 进行降序,在前面加-

    # limit,获取指定数量的记录,一般和offset一起使用
    limit_info = User.query.order_by(User.id).limit(2).all()           # 这里是将查询出来的值,limit(2获取前两条记录
    limit_info1 = User.query.offset(2).limit(2).all()                   # offset(2)表示跳过前两条,limit(2)再获取两条记录






总结:
    1、模型类.query.all()           # 查询所有
    2、模型类.query.get()           # 查询一个
    3、模型类.query.filter()        # 条件
    4、模型类.query.filter_by()     # 条件


删除数据:
    1、逻辑删除:在定义数据库表时,添加一个字段isdelete,通过次字段控制是否删除,判断这个字段的值
        # 从请求中获取到传参id的值
        id = request.args.get('id')
        # 通过id找到对应的用户,因为id是主键,所以get
        id_user = User.query.get(id)
        # # 进行逻辑删除
        ##############################
        # 逻辑删除
        # id_user.isdelete = True
        # db.session.commit()


    2、物理删除:从数据库中彻底删除
        # 从请求中获取到传参id的值
        id = request.args.get('id')
        # 通过id找到对应的用户,因为id是主键,所以get
        id_user = User.query.get(id)
        ######################################
        # 物理删除
        db.session.delete(id_user)      # 将对象放到缓存中
        db.session.commit()             # 提交删除




更新数据:
        id = request.form.get('id')         # 获取到request请求中带的数据,这是从post请求中 ,get请求使用request.ages.get()
        # 通过主键id找到对应的用户
        user_info = User.query.get(id)      # 获取到对应的用户信息
        # 修改用户信息
        user_info.phone = phone             # 修改phone的值
        user_info.username = username       # 修改username的值
        db.session.commit()     # 提交更改,更新对象时不需要add,可直接commit
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值