嘘~ 正在从服务器偷取页面 . . .

MySQL数据库学习(7) -- pymysql简单介绍


pymysql 基本语法及游标移动

import pymysql

conn = pymysql.connect(
    host="127.0.0.1", # 端口
    port=3306,
    user = "root",
    password="", # 密码,该参数可以简写成 passwd=
    database="test", # 连接的库的名称
    charset="utf8", # 读取数据时的编码,一定不要加 “-”
)

# cousor = conn.cursor() # 生成游标,类似于 cmd 中的光标
#
# sql = "select * from dep"

"""
+------+--------------+
| id   | name         |
+------+--------------+
|  200 | 技术         |
|  201 | 人力资源     |
|  202 | 销售         |
|  203 | 运营         |
|  205 | sale         |
+------+--------------+
"""

# res = cousor.execute(sql)
# print(res) # 5  打印的是该 sql 命令影响的数据的行数

# print(cousor.fetchone()) # 拿其中一条数据,元组形式。

# 而实际上我们更希望拿出的数据是 字典形式
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

sql = "select * from dep"

"""
+------+--------------+
| id   | name         |
+------+--------------+
|  200 | 技术         |
|  201 | 人力资源     |
|  202 | 销售         |
|  203 | 运营         |
|  205 | sale         |
+------+--------------+
"""

res = cursor.execute(sql)
print(res) # 5  打印的是该 sql 命令影响的数据的行数

print(cursor.fetchone()) # 拿其中一条数据,此时是 字典形式。
print(cursor.fetchone()) # 执行该命令,拿到的表中第二条数据,原因是因为在第一次执行该命令时,游(光)标 从第一条数据的位置移动到了 第二条数据 的位置,所以此时拿到的是第二条数据,同时游标移动到了第三条数据的位置

# 光标的移动
cursor.scroll(1, "relative") # 相对当前位置往后移动一条数据,即 游标来到了第四条数据
print(cursor.fetchone()) # 第四条数据

cursor.scroll(1, "absolute") # 从头往后移动 一条数据
print(cursor.fetchall()) # 拿所有数据,由于此时 游标在第二条数据上,所以只能拿到四条数据

sql 注入以及解决方法

sql 注入

# 在 test 库中先创建一张 user 表
create table user (
    id int primary key auto_increment,
    name char(16),
    password varchar(32)
);

insert into user(name, password) values
("aoteman", "asd"),
("alterman", "asdzxc");

import pymysql

conn = pymysql.connect(
    host="127.0.0.1",
    port=3306,
    database="test",
    user="root",
    passwd="", # 数据库密码
    charset="utf8"
)

"""
+----+----------+----------+
| id | name     | password |
+----+----------+----------+
|  1 | aoteman  | asd      |
|  2 | alterman | asdzxc   |
+----+----------+----------+
"""

cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

# 简易登录验证
while True:
    username = input("username:>>")
    password = input("password:>>")

    sql = "select * from user where name='%s' and password='%s' " % (username, password)
    print(sql)

    cursor.execute(sql)

    print(cursor.fetchall())

正常登录情况

非正常登录情况

'''
在上述演示的非正常登陆情况下,我们发现
    一种是只知道 用户名就可以实现登录,并且该登录用户的返回密码
    一种是不知道账号和密码的情况下,完成登录,并且获取所有用户的用户名和密码
'''

我们在分析 mysql 在上述两种情况中执行的代码分别是
    select * from user where name='aoteman'#' and password='' 
    select * from user where name='' or 1=1 #' and password='' 
    
分析执行的 sql 语句我们会发现这些非正常登录的情况是因为 用户巧妙运用了 mysql 的逻辑运算(or)和 注释符号 “#” 使得部分代码虽然存在但不执行,从而跳过了密码验证和用户名验证

数据库注入情况是比较常见的,比如说我们在注册一些账户的时候,会要求我们的用户名和密码不能包含一些特殊符号就是为了防止注入的情况出现。

sql 注入的解决方法

# 第一种方法就是在用户注册时明确不能包含特殊符号(适用性较差)

# 第二种方法使用,pymysql 模块提供的方法

sql = "select * from user where name=%s and password=%s "
cursor.execute(sql, (username, password))

在演示中我们可以看到按照这种方法可以比较简单的避免 sql 注入的情况出现

pymysql补充内容

'''
增删改查中
    删、改、增它们的操作涉及到数据的更改,没有办法直接执行,需要二次确认
'''

# 执行多条 sql 语句
rows = cursor.executemany(sql, [("sekiro", "123"), ("ash", "123456")])


import pymysql

conn = pymysql.connect(
    host = "127.0.0.1",
    port = 3306,
    user = "root",
    password = "",
    charset = "utf8",
    database = "test518",
    autocommit = True # 自动提交
)

cursor = conn.cursor(cursor = pymysql.cursors.DictCursor)

# 增加数据
sql = "insert into user(name, password) values(%s, %s)"
# rows = cursor.execute(sql, ("sekiro", "123"))
# 执行多条 sql 语句
rows = cursor.executemany(sql, [("sekiro", "123"), ("ash", "123456")])
print(rows)
# conn.commit() # 确认

# 修改
sql = "update user set name='ash' where id = 1"
rows = cursor.execute(sql)
print(rows)
# conn.commit() # 确认

# 删
sql = "delete from user where id = 1"
rows = cursor.execute(sql)
print(rows)

文章作者: New Ass
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 New Ass !
  目录