1. 安装pymysql

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pymysql

 

2. 使用pymysql 完成数据库连接

import pymysql
from pymysql.cursors import DictCursor


conn = pymysql.connect(host='127.0.0.1', user='root', password='666', database='day09')  # 1、连接数据库 (数据库IP 数据库用户名 数据库用户密码 数据库名)
cursor = conn.cursor(DictCursor)  # 2、获取游标 (默认返回值是元组,DictCursor返回值是字典类型)
sql = "select database()"  # 3、sql语句
cursor.execute(sql)  # 4、执行sql语句
# 5、从游标中拿到查询的数据
# res = cursor.fetchone()  # 拿到一条数据
# res = cursor.fetchmany(2)  # 拿到2条数据
res = cursor.fetchall()  # 拿到所有的数据,游标有个特点,类似于迭代器,数据取完,就取不到了。
print(res)
cursor.close()  # 6、关闭游标
conn.close()  # 7、关闭连接

执行结果:

[{'database()': 'day09'}]

总结:

  1、连接数据库 (数据库IP 数据库用户名 数据库用户密码 数据库名)

  2、获取游标 (默认返回值是元组,DictCursor返回值是字典类型)

  3、sql语句

  4、执行sql语句

  5、从游标中拿到查询的数据

  6、关闭游标

  7、关闭连接

 userinfo表结构

 

/*
 Navicat Premium Data Transfer

 Source Server         : mysql-5.6
 Source Server Type    : MySQL
 Source Server Version : 50644
 Source Host           : localhost:3306
 Source Schema         : day09

 Target Server Type    : MySQL
 Target Server Version : 50644
 File Encoding         : 65001

 Date: 30/12/2019 14:19:59
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for userinfo
-- ----------------------------
DROP TABLE IF EXISTS `userinfo`;
CREATE TABLE `userinfo`  (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `username` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `password` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `username`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 26 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

SET FOREIGN_KEY_CHECKS = 1;

 


3. 使用pymysql完成各种简单的数据库操作 (增加数据)

import pymysql
from pymysql.cursors import DictCursor


# 1、连接数据库 (数据库IP 数据库用户名 数据库用户密码 数据库名)
conn = pymysql.connect(host='127.0.0.1', user='root', password='666', database='day09')
# 2、获取游标 (默认返回值是元组,DictCursor返回值是字典类型)
cursor = conn.cursor(DictCursor)
username = "user2"
password = "123456"
try:
    sql = "insert into userinfo(username, password) values(%s, %s)"  # 3、sql语句(增加)
    cursor.execute(sql, (username, password))  # 4、执行sql语句
    conn.commit()  # 5、提交
    print(f"用户{username}添加成功!")
except Exception as e:
    conn.rollback()  # 事件回滚
    print(e)
finally:
    cursor.close()  # 6、关闭游标
    conn.close()  # 7、关闭连接

 

使用pymysql完成各种简单的数据库操作 (修改数据)

import pymysql
from pymysql.cursors import DictCursor


# 1、连接数据库 (数据库IP 数据库用户名 数据库用户密码 数据库名)
conn = pymysql.connect(host='127.0.0.1', user='root', password='666', database='day09')
# 2、获取游标 (默认返回值是元组,DictCursor返回值是字典类型)
cursor = conn.cursor(DictCursor)
username = "lily"
password = "888888"
try:
    sql = "update userinfo set password=%s where username=%s"  # 3、sql语句(修改)
    cursor.execute(sql, (password, username))  # 4、执行sql语句
    res = conn.commit()  # 5、提交事务
    print(f"用户{username}信息修改成功!")
except Exception as e:
    conn.rollback()  # 事件回滚
    print(e)
finally:
    cursor.close()  # 6、关闭游标
    conn.close()  # 7、关闭连接

 

使用pymysql完成各种简单的数据库操作 (删除数据)

import pymysql
from pymysql.cursors import DictCursor


# 1、连接数据库 (数据库IP 数据库用户名 数据库用户密码 数据库名)
conn = pymysql.connect(host='127.0.0.1', user='root', password='666', database='day09')
# 2、获取游标 (默认返回值是元组,DictCursor返回值是字典类型)
cursor = conn.cursor(DictCursor)
username = "lily"
try:
    sql = "delete from userinfo where username=%s"  # 3、sql语句(删除)
    cursor.execute(sql, (username,))  # 4、执行sql语句
    conn.commit()  # 5、提交
    print(f"用户{username}已删除!")
except Exception as e:
    conn.rollback()  # 事件回滚
    print(e)
finally:
    cursor.close()  # 6、关闭游标
    conn.close()  # 7、关闭连接

 

使用pymysql完成各种简单的数据库操作(查询数据)

import pymysql
from pymysql.cursors import DictCursor


# 1、连接数据库 (数据库IP 数据库用户名 数据库用户密码 数据库名)
conn = pymysql.connect(host='127.0.0.1', user='root', password='666', database='day09')
# 2、获取游标 (默认返回值是元组,DictCursor返回值是字典类型)
cursor = conn.cursor(DictCursor)
sql = "select * from userinfo"  # 3、sql语句(查询)
cursor.execute(sql)  # 4、执行sql语句
res = cursor.fetchall()  # 5、从游标中拿到查询的数据
print(res)
cursor.close()  # 6、关闭游标
conn.close()  # 7、关闭连接

 执行结果:

[{'id': 8, 'username': 'lucy', 'password': 'fd18e1f7b3279116e1ce1f4f3ccafff0'}, {'id': 10, 'username': 'lily', 'password': '123456'}]

 

4. 查询操作(一次获取全部数据)

import pymysql
from pymysql.cursors import DictCursor


conn = pymysql.connect("127.0.0.1", "root", "666", "day09")
cursor = conn.cursor(DictCursor)
sql = "select * from userinfo"
cursor.execute(sql)
lst = cursor.fetchall()  # 获取查询结果(一次获取全部数据)
print(lst)

# for row in cursor:  # 直接循环出结果
#     print(row)

执行结果:

[{'id': 8, 'username': 'lucy', 'password': 'fd18e1f7b3279116e1ce1f4f3ccafff0'}, {'id': 10, 'username': 'lily', 'password': '123456'}]

 

一条一条的取数据

import pymysql
from pymysql.cursors import DictCursor


conn = pymysql.connect("127.0.0.1", "root", "666", "day09")
cursor = conn.cursor(DictCursor)
sql = "select * from userinfo"
cursor.execute(sql)
one = cursor.fetchone()  # 获取查询结果(一条一条的取)
print(one)
two = cursor.fetchone()  # 获取查询结果(一条一条的取)
print(two)

# for row in cursor:  # 直接循环出结果
#     print(row)

执行结果:

{'id': 8, 'username': 'lucy', 'password': 'fd18e1f7b3279116e1ce1f4f3ccafff0'}
{'id': 10, 'username': 'lily', 'password': '123456'}

 

直接循环出结果
import pymysql
from pymysql.cursors import DictCursor


conn = pymysql.connect("127.0.0.1", "root", "666", "day09")
cursor = conn.cursor(DictCursor)
sql = "select * from userinfo"
cursor.execute(sql)
# one = cursor.fetchone()  # 获取查询结果
# print(one)
# two = cursor.fetchone()  # 获取查询结果
# print(two)

for row in cursor:  # 直接循环出结果
    print(row)

执行结果:

{'id': 8, 'username': 'lucy', 'password': 'fd18e1f7b3279116e1ce1f4f3ccafff0'}
{'id': 10, 'username': 'lily', 'password': '123456'}

总结:

  游标取数据只能取一次,取完了,就没有了。除非让游标回滚,下面会提到哦。

python预编译防止sql注入 pymysql 防注入_数据库

python预编译防止sql注入 pymysql 防注入_python预编译防止sql注入_02

python预编译防止sql注入 pymysql 防注入_sql_03

 

python预编译防止sql注入 pymysql 防注入_sql_04

简单理解什么是Cursor游标?

  游标(用来存储多条查询数据的一种数据结构(结果集),它有一个指针,用来从上往下移动,从而达到遍历每条记录的作用)

  游标的作用:(拿出结果集中的一行)

  游标是映射在结果集中一行数据上的位置实体,有了游标,用户就可以访问结果集中的任意一行数据了,

  将游标放置到某行后,即可对该行数据进行操作,例如提取当前行的数据等。

  游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标充当指针的作用。

  尽管游标能遍历结果中的所有行,但他一次只指向一行。

  概括来讲,SQL的游标是一种临时的数据库对象,即可以用来存放在数据库表中的数据行副本,也可以指向存储在数据库中的数据行的指针。

  游标提供了在逐行的基础上操作表中数据的方法。

  游标的一个常见用途就是保存查询结果,以便以后使用。游标的结果集是由SELECT语句产生,如果处理过程需要重复使用一个记录集,那么创建一次游标而重复使用若干次,比重复查询数据库要快的多。

 

5. sql注入以及未来写sql的注意事项

import pymysql
from pymysql.cursors import DictCursor


# 1、连接数据库 (数据库IP 数据库用户名 数据库用户密码 数据库名)
conn = pymysql.connect(host='127.0.0.1', user='root', password='666', database='day09')
# 2、获取游标 (默认返回值是元组,DictCursor返回值是字典类型)
cursor = conn.cursor(DictCursor)
# 让用户名输入用户名和密码
username = input("Username>>>: ").strip()
password = input("Password>>>: ").strip()
sql = f"select * from userinfo where username='{username}' and password='{password}'"  # 3、sql语句
print(sql)
cursor.execute(sql)  # 4、执行sql语句
res = cursor.fetchone()  # 5、从游标中拿到查询的数据
print(res)
if res:
    print("登录成功")
else:
    print("用户名或密码错误!")
cursor.close()  # 6、关闭游标
conn.close()  # 7、关闭连接

执行结果:

Username>>>: lily
Password>>>: 1' or '1'='1
select * from userinfo where username='lily' and password='1' or '1'='1'
{'id': 8, 'username': 'lucy', 'password': 'fd18e1f7b3279116e1ce1f4f3ccafff0'}
登录成功

上面的执行结果,可以看到成功的被注入了。

 

防止sql注入的正确写法

import pymysql
import hashlib
from pymysql.cursors import DictCursor


def get_md5(str1):
    """
    md5加密
    :param str1:
    :return:
    """
    md5_obj = hashlib.md5("我是盐字符串,我越复杂越不容易被破解哦!".encode("utf-8"))
    md5_obj.update(str1.encode("utf-8"))
    return md5_obj.hexdigest()


# 1、连接数据库 (数据库IP 数据库用户名 数据库用户密码 数据库名)
conn = pymysql.connect(host='127.0.0.1', user='root', password='666', database='day09')
# 2、获取游标 (默认返回值是元组,DictCursor返回值是字典类型)
cursor = conn.cursor(DictCursor)
# 让用户名输入用户名和密码
username = input("Username>>>: ").strip()
password = get_md5(input("Password>>>: ").strip())
sql = "select * from userinfo where username=%s and password=%s"  # 3、sql语句
cursor.execute(sql, (username, password))  # 4、执行sql语句
# sql = "select * from userinfo where username=%(username)s and password=%(password)s"  # 3、sql语句
# cursor.execute(sql, {"username": username, "password": password})  # 4、执行sql语句
res = cursor.fetchone()  # 5、从游标中拿到查询的数据
print(res)
if res:
    print("登录成功")
else:
    print("用户名或密码错误!")
cursor.close()  # 6、关闭游标
conn.close()  # 7、关闭连接

 执行结果:

Username>>>: lily
Password>>>: 1' or '1'='1
select * from userinfo where username=%(username)s and password=%(password)s
None
用户名或密码错误!
Username>>>: lily
Password>>>: 123456
select * from userinfo where username=%(username)s and password=%(password)s
{'id': 10, 'username': 'lily', 'password': '123456'}
登录成功

以后都要这样写哦!

 

6.通过密码加密也可以防止sql注入(增加用户)

import pymysql
import hashlib
from pymysql.cursors import DictCursor


def get_md5(str1):
    """
    md5加密
    :param str1:
    :return:
    """
    md5_obj = hashlib.md5("我是盐字符串,我越复杂越不容易被破解哦!".encode("utf-8"))
    md5_obj.update(str1.encode("utf-8"))
    return md5_obj.hexdigest()


# 1、连接数据库 (数据库IP 数据库用户名 数据库用户密码 数据库名)
conn = pymysql.connect(host='127.0.0.1', user='root', password='666', database='day09')
# 2、获取游标 (默认返回值是元组,DictCursor返回值是字典类型)
cursor = conn.cursor(DictCursor)
try:
    # 手动输入要插入的用户名和密码,并对密码加密处理
    username = input("Username>>>: ").strip()
    password = get_md5(input("Password>>>: ").strip())
    sql = f"insert into userinfo(username, password) values(%s, %s)"  # 3、sql语句(增加)
    cursor.execute(sql, (username, password))  # 4、执行sql语句
    conn.commit()  # 5、提交
except Exception as e:
    conn.rollback()  # 事件回滚
    print(e)
finally:
    cursor.close()  # 6、关闭游标
    conn.close()  # 7、关闭连接

 执行结果:

Username>>>: aaa
Password>>>: 123456

 

通过密码加密也可以防止sql注入(修改信息)

import pymysql
import hashlib
from pymysql.cursors import DictCursor


def get_md5(str1):
    """
    md5加密
    :param str1:
    :return:
    """
    md5_obj = hashlib.md5("我是盐字符串,我越复杂越不容易被破解哦!".encode("utf-8"))
    md5_obj.update(str1.encode("utf-8"))
    return md5_obj.hexdigest()


# 1、连接数据库 (数据库IP 数据库用户名 数据库用户密码 数据库名)
conn = pymysql.connect(host='127.0.0.1', user='root', password='666', database='day09')
# 2、获取游标 (默认返回值是元组,DictCursor返回值是字典类型)
cursor = conn.cursor(DictCursor)
# 让用户名输入用户名和密码
username = input("Username>>>: ").strip()
password = get_md5(input("Password>>>: ").strip())
try:
    sql = f"update userinfo set password=%s where username=%s"  # 3、sql语句(修改)
    cursor.execute(sql, (password, username))  # 4、执行sql语句
    res = conn.commit()  # 5、提交事务
    print(f"用户{username}密码修改成功!")
except Exception as e:
    conn.rollback()  # 事务回滚
    print(e)
finally:
    cursor.close()  # 6、关闭游标
    conn.close()  # 7、关闭连接

 执行结果:

Username>>>: aaa
Password>>>: 654321

 

查询

import pymysql
import hashlib
from pymysql.cursors import DictCursor


def get_md5(str1):
    """
    md5加密
    :param str1:
    :return:
    """
    md5_obj = hashlib.md5("我是盐字符串,我越复杂越不容易被破解哦!".encode("utf-8"))
    md5_obj.update(str1.encode("utf-8"))
    return md5_obj.hexdigest()


# 1、连接数据库 (数据库IP 数据库用户名 数据库用户密码 数据库名)
conn = pymysql.connect(host='127.0.0.1', user='root', password='666', database='day09')
# 2、获取游标 (默认返回值是元组,DictCursor返回值是字典类型)
cursor = conn.cursor(DictCursor)
# 让用户名输入用户名和密码
username = input("Username>>>: ").strip()
password = get_md5(input("Password>>>: ").strip())
sql = "select * from userinfo where username=%(username)s and password=%(password)s"  # 3、sql语句
cursor.execute(sql, {"username": username, "password": password})  # 4、执行sql语句
res = cursor.fetchone()  # 5、从游标中拿到查询的数据
print(res)
if res:
    print("登录成功")
else:
    print("用户名或密码错误!")
cursor.close()  # 6、关闭游标
conn.close()  # 7、关闭连接

 执行结果:

Username>>>: lily
Password>>>: 111111
{'id': 24, 'username': 'lily', 'password': 'f40f52c856e5fc1225fff462ff1e1a2a'}
登录成功