在python2.7种主要用的是MySQLdb模块,在python3.X版本中用的是pymysql模块,两者的用法是完全一样的,就是名字不同而已。安装模块的方法主要是用pip命令,下面我用pymysql模块做分析。
一、数据库信息
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import pymysql
PY_MYSQL_CONN_DICT = {
"host": '127.0.0.1',
"port": 3306,
"user": 'root',
"passwd": 'root',
"db": 'test',
"charset": 'utf8',
"use_unicode":False #如果为True,可能会导致内存泄露
}
二、连接和关闭数据库
#连接数据库
conn = pymysql.connect(**PY_MYSQL_CONN_DICT) #连接数据库
cursor = conn.cursor() #创建游标,后面针对数据库的操作主要是用游标
#关闭数据库连接
conn.commit() #这个命令主要是如果对数据进行了更新或者添加或者删除操作,通过提交才能同步到数据库
cursor.close() #关闭游标
conn.close() #关闭连接
#=================比较完整的命令=================
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import pymysql
PY_MYSQL_CONN_DICT = {
"host": '127.0.0.1',
"port": 3306,
"user": 'root',
"passwd": 'root',
"db": 'test',
"charset": 'utf8'
}
conn = pymysql.connect(**PY_MYSQL_CONN_DICT) #连接数据库
cursor = conn.cursor() #创建游标
#对数据库的操作
sql = "要执行的sql语句"
cursor.execute(sql) #执行sql
cursor.fetchall() #通过执行sql,获取所有返回的信息
#cursor.fetchone() #通过执行sql,获取返回信息中的一条
conn.commit() #如果只是查询操作,这个命令可以不用加
cursor.close()
conn.close()
三、操作数据库(主要是通过游标实现)
1、增
①字符串拼接的SQL,可以执行,一般不用这样用
inp = input('请输入班级:')
sql = 'insert into class(caption) values("%s")'
sql = sql % (inp,)
cursor.execute(sql)
②参数传递,推荐用这种
inp = input('请输入班级:')
#cursor.execute('insert into class(caption) values("%s")',inp) #这样在数据库插入的格式会变成 '内容'
cursor.execute('insert into class(caption) values(%s)',inp) #这样在数据库插入的格式是我们想要的
③传入多个参数
cursor.execute('insert into class(id,caption,school) values(%s,%s,%s)',(1,'094班','WuHan')) #以元组形式出入
④插入多条数据,用executemany
info = [
(1,'094班','WuHan'),
(2,'095班','WuHan'),
(3,'096班','WuHan'),
]
cursor.executemany('insert into class(id,caption,school) values(%s,%s,%s)',info)
2、删
cursor.execute('delete from class where uid=%s',(1,))
3、改
cursor.execute('update class set caption=%s where uid=%s',('093班',1))
备注:
1、在执行完fetchone后,游标的相对和绝对位置
cursor.scroll(0,mode='absolute') #游标绝对位置
cursor.scroll(0,mode='relative') #游标相对位置
2、通过sql字符串拼接,导致sql注入的形式
sql = sql % ('095班" or 1=1 --',2)
#这样主要是因为sql的注释为 '--'
四、生产中操作
在生产过程中,如果操作一条sql就建立一次tcp的链接,这样对数据库的性能消耗是比较大的,所以我们一般采用单例模式,即将连接的状态保存下来,后面在调用的时候直接调用这个状态。
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import pymysql
PY_MYSQL_CONN_DICT = {
"host": '127.0.0.1',
"port": 3306,
"user": 'root',
"passwd": 'root',
"db": 'test',
"charset": 'utf8'
}
#将连接mysql的状态写成一个类
class DbConnection(object):
def __init__(self):
self.__conn_dict = PY_MYSQL_CONN_DICT
self.conn = None
self.cursor = None
def connect(self, cursor=pymysql.cursors.DictCursor):
self.conn = pymysql.connect(**self.__conn_dict)
self.cursor = self.conn.cursor(cursor=cursor)
return self.cursor
def close(self):
self.conn.commit()
self.cursor.close()
self.conn.close()
#调用
class PermissionRepository(object):
def __init__(self):
self.db_conn = DbConnection()
def add(self, **kwargs):
cursor = self.db_conn.connect()
sql = """ insert into permission(%s) values(%s)"""
key_list = []
value_list = []
for k, v in kwargs.items():
key_list.append(k)
value_list.append('%%(%s)s' % k) #%的转义符在mysql中必须是%
sql = sql % (','.join(key_list), ','.join(value_list))
cursor.execute(sql, kwargs)
self.db_conn.close()
def fetch_all(self):
cursor = self.db_conn.connect()
sql = """要执行的sql语句"""
cursor.execute(sql)
result = cursor.fetchall()
#result = cursor.fetchone() 获取查询结果中的一条数据
#result = cursor.fetchmany() 获取查询结果中的多条数据
self.db_conn.close()
return result
拓展知识:
python动态导入模块
import importlib
func_name = 'add'
module = 'src.commons'
m = importlib.import_module(module)
func = getattr(m,func_name)
func()
print(m)