pymysql

pymysql

安装: pip install pymysql

一般流程

	建立连接
	获取游标
	执行SQL
	提交事务
	释放资源

连接Connect

首先建立连接
pymsql.connect()方法返回的Connection实例

conn=pymysql.connect(host='服务器',
                     user='用户',
                     password='密码',
                     port=端口,
                     db='库名',
                     charset='字符集')

注意点:port=3306 不能用引号 否则报错
存在中文的时候,连接需要添加charset=‘utf8’,否则中文显示乱码。
connect方法传参

参数说明
host指的是数据库服务器的主机地址
user连接数据库的用户
password连接数据库的密码
database连接的数据库名
port端口
charset字符集

游标Cursor

操作数据库,必须使用游标,需要先获取一个游标对象
Connection.cursor(cursor=None)方法返回一个新的游标对象
连接没有关闭前,游标对象可以反复使用

cursor参数,可以指定一个Cursor类,如果为None,则使用默认Cursor类

cursor=conn.cursor()

execute()方法

执行SQL语句,返回受影响的行数
这里和java的jdbc有点不一样不管是增删改,还是差返回的都是受影响的行数,而java查返回的是一个结果集,python的查询的返回值可以理解为查到的数量

查询

count=cursor.execute('select * from person')
print(count)

增删改

try:
    count=cursor.execute("insert into t_user (id,username,password,hobby,email) values ('1004','dyk','123','乒乓球','111111')")
    print(count)
    conn.commit() #提交
   # 不然无法保存新建或者修改的数据

except Exception as e:
    conn.rollback() #回滚
finally:
    cursor.close()
    conn.close()

插入多行可以写在一个列表里当参数一次性传入

与查寻不同的是:成功需要commit()提交 失败需要rollback()撤销,如果不写提交即便执行成功数据库里面也没有改动

查询

Cursor类的获取查询结果集的方法有
fetchone()方法获取单条数据,使用fetchall()方法获取多条数据获取指定条数fetchmany(size=None)

方法与属性说明
fetchone()获取查询结果集中的一条数据,返回的是一个元组
fetchmany(size=None)size指定返回的行数,None则返回空元组
fetchall()返回剩下的所有行,如果走到末尾,就返回空元组,否则返回一个元组,其元素是每一行的记录封装的一个元组
cursor.rowcount这是一个只读属性,并返回执行execute()方法后影响的行数
cursor.rownumber返回当前行号.可以修改,支持负数
cursor.lastrowid可以获取到最新自增的ID,也就是最后插入的一条数据ID
import pymysql

conn=pymysql.connect(host='localhost',user='root',password='123456',database='db3',port=3306,charset='utf8')
cursor=conn.cursor()

try:
    count=cursor.execute('select * from person')
    #count=cursor.execute("insert into t_user (id,username,password,hobby,email) values ('1005','dyk','123','乒乓球','111111')")
    print(count) #1
    print(cursor.rowcount) #1
    
    print(cursor.rownumber) #0
    info=cursor.fetchone()
    print(cursor.rownumber)  #1
    
    print(info) #(1, 'dyk1234', 18, datetime.date(2000, 3, 7), '1106649325', 'jm')
    
    print(type(info)) #<class 'tuple'>

    conn.commit()

except Exception as e:
    conn.rollback()
finally:
    if conn:
        conn.close()
    if cursor:
        cursor.close()
import pymysql

conn=pymysql.connect(host='localhost',user='root',password='123456',database='db3',port=3306,charset='utf8')
cursor=conn.cursor()

try:
    count=cursor.execute('select * from person')
    #count=cursor.execute("insert into t_user (id,username,password,hobby,email) values ('1005','dyk','123','乒乓球','111111')")
    print(cursor.rownumber) #0
    info=cursor.fetchall()
    print(cursor.rownumber) #3
    for f in info:

        print(f)
    conn.commit()

except Exception as e:
    conn.rollback()
finally:
    if conn:
        conn.close()
    if cursor:
        cursor.close()


#(1, 'dyk1234', 18, datetime.date(2000, 3, 7), '1106649325', 'jm')
#(5, 'cb', 18, datetime.date(2000, 3, 8), '1106649325', 'jm')
#(7, 'dyk1234', 18, datetime.date(2000, 3, 7), '1106649325', 'jm')

注意:fetch操作的是结果集,结果集是保存在客户端的,也就是说fetch的时候,查询已经结束了.

获取的时候,这个类似于文件的读取操作,文件指针,例如先用了fetchall()就相当于走到末尾,再用fetchone就没用了

关于默认获取的数据是元祖类型,如果想要或者字典类型的数据,即:

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

conn = pymysql.connect(host='localhost', user='root', password='123456', database='db3', port=3306, charset='utf8')
cursor = conn.cursor(pymysql.cursors.DictCursor)

try:
    count = cursor.execute('select * from person')

    info = cursor.fetchone()
    print(info)  #{'id': 1, 'name': 'dyk1234', 'age': 18, 'borndate': datetime.date(2000, 3, 7), 'email': '1106649325', 'address': 'jm'}

    print(type(info))  #<class 'dict'>

    conn.commit()

except Exception as e:
    conn.rollback()
finally:
    if conn:
        conn.close()
    if cursor:
        cursor.close()

sql注入

SQL注入(SQLi)是一种注入攻击,,可以执行恶意SQL语句。它通过将任意SQL代码插入数据库查询,使攻击者能够完全控制Web应用程序后面的数据库服务器。攻击者可以使用SQL注入漏洞绕过应用程序安全措施;可以绕过网页或Web应用程序的身份验证和授权,并检索整个SQL数据库的内容;还可以使用SQL注入来添加,修改和删除数据库中的记录。

import pymysql

conn=pymysql.connect(host='localhost',user='root',password='123456',database='db3',port=3306,charset='utf8')
cursor=conn.cursor()
username=input('请输入用户名:')
password=input('请输入密码:')
try:

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

    cursor.execute(sql)
    print(cursor.fetchone())
    conn.commit()

except Exception as e:
    conn.rollback()
finally:
    if conn:
        conn.close()
    if cursor:
        cursor.close()

这样虽然正常的账号密码输入正确和错误也行,但是如果是
例如

如数username的时候输入zhangsan"#
那么密码无论输入什么都会登录成功
因为拼接后的字符串被#给注释掉了

解决注入攻击的方法

参数化查询,可以有效防止注入攻击,并提高查询的效率

Cursor.execute(query,args=None) args必须是元组 列表或字典

有点像java里面的statement和preparestatement的区别

import pymysql

conn=pymysql.connect(host='localhost',user='root',password='123456',database='db3',port=3306,charset='utf8')
cursor=conn.cursor()
username=input('请输入用户名:')
password=input('请输入密码:')
try:

    sql = 'select * from login where username=%s and password=%s'

    cursor.execute(sql,[username,password])
    print(cursor.fetchone())
    conn.commit()

except Exception as e:
    conn.rollback()
finally:
    if conn:
        conn.close()
    if cursor:
        cursor.close()

execute方法中的 %s 占位不需要带引号

还可以批量执行 executemany()

使用with简化连接过程

每次都连接关闭很麻烦,使用上下文管理,简化连接过程

import pymysql

conn = pymysql.connect(host='localhost', user='root', password='123456', database='db3', port=3306, charset='utf8')
with conn.cursor() as cursor:

    try:
        count = cursor.execute('select * from person')

        info = cursor.fetchone()

        print(info)

        conn.commit()

    except Exception as e:
        conn.rollback()
    finally:
        if conn:
            conn.close()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值