本篇对于Python操作MySQL主要使用两种方式:
- 原生模块 pymsql
- ORM框架 SQLAchemy
参考资料:http://www.runoob.com/python/python-mysql.html
一、pymsql
pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同。
下载安装
pip3 install pymysql -i https://pypi.douban.com/simple
使用操作
1、执行SQL
写sql语句的时候,如果在操作前sql语句字符串格式化,占位符%s要引号' '引起来,如果执行操作,以元组或者列表的形式,在提交的时候传递参数,则占位符%s就不能引号引起来。
import pymysql
user = input("username:")
pwd = input("password:")
# 创建连接
conn = pymysql.connect(host="localhost",user='root',password='',database="db666")
# 出现编码问题conn = pymysql.connect(host="localhost",user='root',password='',database="db666",charset="utf8")
# 创建游标
cursor = conn.cursor()
sql = "select * from userinfo where username='%s' and password='%s'" %(user,pwd,)
# select * from userinfo where username='uu' or 1=1 -- ' and password='%s' #sql注入
# 执行SQL,并返回收影响行数
cursor.execute(sql)
# 获取第一行数据
result = cursor.fetchone()
cursor.close()
conn.close()
if result:
print('登录成功')
else:
print('登录失败')
注意:存在中文的时候,连接需要添加charset='utf8',否则中文显示乱码。
获取查询数据
结论:excute执行SQL语句的时候,必须使用参数化的方式,否则必然产生SQL注入漏洞。
import pymysql user = input("username:") pwd = input("password:") conn = pymysql.connect(host="localhost",user='root',password='',database="db666") cursor = conn.cursor() sql = "select * from userinfo where username=%s and password=%s" cursor.execute(sql,(user,pwd)) #推荐这种方法,防止sql注入
# cursor.execute(sql,[user,pwd]) # cursor.execute(sql,{'u':user,'p':pwd}) #查询一行
result = cursor.fetchone()
#查询全部
result = cursor.fetchall()
#查询四行
result = cursor.fetchmany(4)
cursor.close() conn.close() if result: print('登录成功') else: print('登录失败')
注:在fetch数据时按照顺序进行,可以使用cursor.scroll(num,mode)来移动游标位置,如:
- cursor.scroll(1,mode='relative') # 相对当前位置移动
- cursor.scroll(2,mode='absolute') # 相对绝对位置移动
插入多行数据
conn = pymysql.connect(host="localhost",user='root',password='',database="db666") cursor = conn.cursor() sql = "insert into userinfo(username,password) values(%s,%s)" # 插入多行数据 r = cursor.executemany(sql,[('egon','sb'),('laoyao','BS')]) # ****** # 提交,不然无法保存新建或者修改的数据 conn.commit() cursor.close() conn.close()
报错信息: Error: unable to insertdb! insert into class(title) values(%s) not all arguments converted during string formatting sql = "insert into class(title) values(%s)" li = [('1期',), ('2期',)] # 只插入一列时这么写可以解决,sql语句也不能%s也不能‘’引起来
cursor.executemany(sql,li)
#sql = "insert into userinfo(name,email,gender_id) values(%s,%s,%s)"
#db.insertmanydb(sql, [('egon', 'sb',1), ('laoyao', 'BS',1)])
fetch数据类型
关于默认获取的数据是元祖类型,如果想要或者字典类型的数据,即:
# 查 conn = pymysql.connect(host="localhost",user='root',password='',database="db666") # 游标设置为字典类型 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = "select * from userinfo" cursor.execute(sql) cursor.scroll(1,mode='relative') # 相对当前位置移动 cursor.scroll(2,mode='absolute') # 相对绝对位置移动 # 查询一行 result = cursor.fetchone() print(result) # 查询全部 result = cursor.fetchall() print(result) # 查询4行 result = cursor.fetchmany(4) print(result) cursor.close() conn.close()
插入单条数据,获取新创建数据自增ID
# 新插入数据的自增ID: cursor.lastrowid import pymysql conn = pymysql.connect(host="localhost",user='root',password='',database="db666") cursor = conn.cursor() sql = "insert into userinfo(username,password) values('asdfasdf','123123')" cursor.execute(sql) conn.commit() # 新插入数据的自增ID,插入多条时也是拿到最后一条的ID print(cursor.lastrowid) cursor.close() conn.close()
sql语句插入中内容同时包含单引号和双引号的解决办法
在python中调用MySQLdb模块插入数据信息,假设待输入信息data为:
Hello'World"!
其中同时包含了单引号和双引号
一般插入语句为
sql = "insert into tb (my_str) values('%s')" % (data) cursor.execute(sql)
其中values('%s')中的%s外面也要有引号,这个引号与data中的引号匹配导致了内容错误
解决办法一: MySQLdb.escape_string()
在MySQLdb模块中自带针对mysql的转义函数escape_string(),直接调用即可
sql = "insert into tb (my_str) values('%s')" % (MySQLdb.escape_string(data)) cursor.execute(sql)
解决办法二:转义字符
将data变为下面的形式,再插入数据库就正确了
Hello\'World\"!
具体在python中的转义函数如下:
def transferContent(self, content): if content is None: return None else: string = "" for c in content: if c == '"': string += '\\\"' elif c == "'": string += "\\\'" elif c == "\\": string += "\\\\" else: string += c return string
要加三个\,这是因为\\会在函数中转义为\,\'会转义成',两者合起来才能在字符串中留下 \',然后sql读取后才能识别这是转义
注意,\本身也需要转义,否则如果原本字符串中为\',只转义'就会变成\\\\',结果是\\\\相互抵消,只剩下'
在python中,下面两种写法是一样的
a=" ' " a=" \' "
二、SQLAchemy
SQLAlchemy是Python编程语言下的一款ORM(关系对象映射)框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执行结果。
Object Relational Mapper (ORM) 关系对象映射(就是自己写的类)
Schema/Type 、SQL Expression Lanuage将类转换成SQL语句
DBAPI就是(pymysql、mysqlDB、SQL、oracle等中间件接口),通过这些东西连接不同的数据库
Engine(引擎启动),然后去connection pooling连接池看建立几个连接,然后去Dialect拿配置(如mysql+pymysql),通过中间件接口连接对应数据库
安装:
pip3 install SQLAlchemy
面向对象:
class Foo: def __init__(self,name): self.name = name def show(self): print(self.name) def __call__(self): pass def __getitem__(self,key): pass def __setitem__(self,key,value): pass def __delitem__(self,key): pass obj1 = Foo('eric') obj1() 执行__call__方法 obj1['k'] 执行__getitem__方法 obj1['k'] = 123 执行__setitem__方法 del obj[k] 执行__delitem__方法 obj.__dict__对象的全部属性