Python_pymysql连接数据库_Flask初学

Python操作Mysql有很多方法

Pymysql

Pymysql是Python3的一个MySQL数据库驱动程序,它遵循Python DB API v2.0规范,并支持事务、存储过程、多线程操作等。

Python DB API v2.0是Python官方定义的数据库API规范,它为Python程序提供了统一的数据库访问接口,使得Python程序可以使用不同的数据库后端,而不需要修改程序代码。Python DB API v2.0规范定义了一系列的标准API,包括连接数据库、执行SQL语句、获取结果集、事务处理、异常处理等。

游标

在Python中,游标是一种用于在数据库中移动和管理数据的对象。游标可以在结果集中移动,从而允许程序员对数据进行逐行处理。游标还可以用于执行事务和管理数据库连接。

在Python中,游标的概念对应于在 Java 中 JDBC 中的 ResultSet 对象。ResultSet 对象是一个包含查询结果的表格,可以使用游标来遍历其中的行和列。与 Python 中的游标类似,ResultSet 对象也可以用于执行查询和更新操作,以及管理数据库连接和事务。但是,需要注意的是,Java 和 Python 中的游标实现方式略有不同,因此在使用时需要根据具体的语言和框架进行调整。

不开游标,就是将查询结果直接打印出来,没有其他操作。

开了游标,先存放所有结果,让后提供一个游标接口,逐行读取数据直到结束,类似于sed,awk的逻辑。

Pymysql查

远程连接的时候要执行以下操作

在配置文件加入bind-address=0.0.0.0

关闭防火墙就不用说了

在MySQL进行赋权,默认安装的mysql的root用户只支持本地连接。Host为localhsot,要改为%

mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> update user set host='%' where user='root';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT ALL ON *.* TO 'root'@'%';
Query OK, 0 rows affected (0.00 sec)

 在python端进行cryptography更新

cryptography是一个用于处理加密和解密的Python包

在终端进行下面命令

pip install cryptography --upgrade
pip show cryptography

最后执行程序如下

import pymysql


def connect_mysql_read():
    # 数据库连接
    con1 = pymysql.connect(host='192.168.126.143', port=3306,
                           user='root', password='Ch#123456',
                           database='test')
    # 获取游标
    con1.cursor = con1.cursor()
    # 执行语句
    read_query = "SELECT * FROM student;"
    con1.cursor.execute(read_query)
    print(con1.cursor.fetchall())
    # 关闭连接游标
    con1.close()
    con1.cursor.close()
    return 0


if __name__ == "__main__":
    connect_mysql_read()

# ((1, '大乔', '2000100101'), (2, '二乔', '2000100102'), (3, '三乔', '2000100103'), (4, '四
# 乔', '2000100104'), (5, '五乔', '2000100105'), (6, '六乔', '2000100106'))

Pymysql增删改

逻辑上是一样的,区别在此类操作通常是批量的,用executemany()更多一点

写操作可能会出现异常,要使用捕获异常方法,且还要中断并回滚。

PyMysql 会将 SQL 语句中的所有字段当做字符串进行处理,所以这 里的no字段在 SQL 中被当做字符串处理

def connect_mysql_write():
    # 数据库连接
    con2 = pymysql.connect(host='192.168.126.143', port=3306,
                           user='root', password='Ch#123456',
                           database='test')
    # 获取游标
    con2.cursor = con2.cursor()
    # 执行语句
    insert_query = "INSERT INTO student VALUES( null,% s, %s)"
    # 待插入的数据
    datas = [("菲尼克斯", 12), ("圣祈", 23), ("雷娜", 34)]
    try:
        con2.cursor.executemany(insert_query, datas)
        # 提交事务
        con2.commit()
    except Exception as e:
        print('输入异常')
        print(e)
        con2.cursor.db.rollback()
    # 关闭连接游标
    con2.close()
    con2.cursor.close()


if __name__ == "__main__":
    # connect_mysql_read()
    connect_mysql_write()

结果如下,因为之前几次执行程序忘记了写commit()提交事务,所以执行了好几次对游标的操作,id是自增主键,游标从20开始插入数据(好像无意间更参透了游标的工作逻辑)

 删和改就不写了,其实就是改一改sql语句

Flask

Flask 是一个使用 Python 编写的轻量级 Web 应用程序框架,使用简单的核心,用extension增加其他功能。

框架表示一个库和模块的集合,上面有很多已经完成的功能,未来可能有更多的功能,用于开发人员使用,无需做重复,复杂抽象的一些东西。(个人理解)

Web框架就能使Web应用程序开发人员能够编写应用程序,而不必担心协议,线程管理等低层但通用的细节。

还有很多概念都不细讲了,我只是初学者,不能胡说八道

基于flask框架写出的用户登录注册界面的html文件以及python代码。将用户名和加密后的密码储存在数据库中。

(网页背景图来自互联网,可能会失效,并没有密码错误多次就冻结的效果,不用注册登录直接写入/succes也能看到成功页面,在浏览器上并没有看到flash消息闪现)

from flask import Flask, render_template, request, redirect, url_for, flash, session
import pymysql
from werkzeug.security import generate_password_hash, check_password_hash

app = Flask(__name__)
app.secret_key = 'your_secret_key'


def connect_mysql():
    con1 = pymysql.connect(host='192.168.126.143', port=3306,
                           user='root', password='Ch#123456',
                           database='test')
    return con1


@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        remember = 'remember_me' in request.form
        conn = connect_mysql()
        cursor = conn.cursor()
        cursor.execute("SELECT password FROM user_info WHERE username = %s", (username,))
        result = cursor.fetchone()
        if result and check_password_hash(result[0], password):
            flash('登录成功!', 'success')
            session['username'] = username
            return redirect(url_for('success'))
        else:
            flash('登录失败,请检查用户名和密码。', 'danger')
        # 及时关闭,不然我发现mysql会锁住
        conn.close()
        cursor.close()
    return render_template('login.html')


@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        confirm_password = request.form['confirm_password']

        if password != confirm_password:
            flash('两次输入的密码不一致。', 'danger')
            return redirect(url_for('register'))
        hashed_password = generate_password_hash(password, method='sha256')
        conn = connect_mysql()
        cursor = conn.cursor()
        cursor.execute("INSERT INTO user_info (username, password) VALUES (%s, %s)", (username, hashed_password))
        conn.commit()
        # 及时关闭,不然我发现mysql会锁住
        conn.close()
        cursor.close()
        flash('注册成功!您现在可以登录。', 'success')
        return redirect(url_for('login'))
    return render_template('register.html')


@app.route('/success')
def success():
    return render_template('success.html', username=session.get('username'))


if __name__ == '__main__':
    app.run(debug=True)

login.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      background:  url('https://img2.doubanio.com/view/photo/l/public/p2561828903.jpg') no-repeat;
      background-size: 100% 130%;
    }

    #login_box {
      width: 20%;
      height: 400px;
      background-color: #00000060;
      margin: auto;
      margin-top: 10%;
      text-align: center;
      border-radius: 10px;
      padding: 50px 50px;
    }

    h2 {
      color: #ffffff90;
      margin-top: 5%;
    }

    #input-box {
      margin-top: 5%;
    }

    span {
      color: #fff;
    }

    input {
      border: 0;
      width: 60%;
      font-size: 15px;
      color: #fff;
      background: transparent;
      border-bottom: 2px solid #fff;
      padding: 5px 10px;
      outline: none;
      margin-top: 10px;
    }

    button {
      margin-top: 50px;
      width: 60%;
      height: 30px;
      border-radius: 10px;
      border: 0;
      color: #fff;
      text-align: center;
      line-height: 30px;
      font-size: 15px;
      background-image: linear-gradient(to right, #30cfd0, #330867);
    }

    #sign_up {
      margin-top: 45%;
      margin-left: 60%;
    }

    a {
      color: #b94648;
    }
  </style>
</head>

<body>
  <div id="login_box">
    <h2>LOGIN</h2>
    <form action="/login" method="post">
      <div id="input_box">
        <input type="text" name="username" placeholder="请输入用户名" required>
      </div>
      <div class="input_box">
        <input type="password" name="password" placeholder="请输入密码" required>
      </div>
      <div>
        <input type="checkbox" name="remember_me" id="remember_me">
        <label for="remember_me">记住密码</label>
      </div>
      <button type="submit">登录</button><br>
    </form>
    <div>
      <a href="/register">注册</a>
    </div>
  </div>
</body>
</html>

register.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>注册页面</title>
  <style>
    body {
      background:  url('https://img2.doubanio.com/view/photo/l/public/p2561828903.jpg') no-repeat;
      background-size: 100% 130%;
    }

    #login_box {
      width: 20%;
      height: 400px;
      background-color: #00000060;
      margin: auto;
      margin-top: 10%;
      text-align: center;
      border-radius: 10px;
      padding: 50px 50px;
    }

    h2 {
      color: #ffffff90;
      margin-top: 5%;
    }

    #input-box {
      margin-top: 5%;
    }

    span {
      color: #fff;

  </style>
</head>

<body>
  <div id="login_box">
    <h2>注册</h2>
    <form action="/register" method="post">
      <div id="input_box">
        <input type="text" name="username" placeholder="请输入用户名" required>
      </div>
      <div class="input_box">
        <input type="password" name="password" placeholder="请输入密码" required>
      </div>
      <div class="input_box">
        <input type="password" name="confirm_password" placeholder="请确认密码" required>
      </div>
      <button type="submit">注册</button><br>
    </form>
    <div>
      <a href="/login">已有账号?登录</a>
    </div>
  </div>
</body>
</html>

success.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>登录成功</title>
    <style>
        body {
            background: #eff0f1;
        }
        .success-container {
            width: 400px;
            margin: 200px auto;
            text-align: center;
            background: #fff;
            border-radius: 5px;
            padding: 20px;
        }
        .success-img {
            width: 200px;
        }
    </style>
</head>
<body>
    <div class="success-container">
        <img class="success-img" src="https://img.soogif.com/oMoxAAWRVXZvHB9SkuMbWrh89IrB4Ogj.gif">
        <h1>登录成功!</h1>
        <p>欢迎回来,<span>用户:{{username}}</span>!</p>
    </div>
</body>
</html>

效果

登录页面

 

 注册页面

 以用户名为‘henry’,密码为‘123’进行登录

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值