一、编码问题

使用mysql 进行中文数据插入时,经常会遇到插入的数据变乱码的问题。这里以经常用的utf8 编码为例,需要在创建数据库时先指定编码为utf8 ,如下:

1create database test character set uft8;

在使用python MySQLdb进行连接时,使用以下代码:

1#!/usr/bin/python
2# encoding: utf-8
3import MySQLdb
4# 打开数据库连接
5db = MySQLdb.connect("localhost","root","361way","test",charset="utf8",init_command="set names utf8" )

经测试,我在centos6.5 python2.66 版本上测试是插入的汉字不再是乱码,而我也看到网上有人给出了通过sys模块处理的方法,代码示例如下:

1#encoding=utf-8
2 import sys
3 import MySQLdb
4 reload(sys)
5 sys.setdefaultencoding('utf-8')
6 db=MySQLdb.connect(user='root',charset='utf8')

注:通过sys代码处理的方式未测试。

二、数据插入的方式

数据在插入时可以支持直接通过字符串(string)方式插入,也支持通过占位符(如%s) 传参的方式插入,也支持以键值对的方式插入。

先创建一张测试表:

1CREATE TABLE blog (
2    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
3    author varchar(10) DEFAULT NULL,
4    context text
5);

于定义一个MySQLdb连接:

1#!/usr/bin/python
2# encoding: utf-8
3import MySQLdb
4# 打开数据库连接
5db = MySQLdb.connect("localhost","root","361way","test",charset="utf8",init_command="set names utf8" )
6# 使用cursor()方法获取操作游标
7cursor = db.cursor()

1、字符串插入

1sql="insert into blog (author, context) values ('admin', '361way is the best site')"
2cursor.execute(sql)

2、元组(tuple)插入方式

1sql="insert into blog (author, context) values (%s,%s)"
2data=("361way",10000)
3cursor.execute(sql,data)

这里使用两个占用符表示要插入的数据,将两个变量的值赋予一个元组内,在执行sql 时将该元组传入即可。

data元组里的两个值,也可以是两个变量,如下:

1var_a="361way"
2var_b=10000
3data=(var_a, var_b)
4cursor.execute(sql,data)

该方法同样适用于字典和列表传入数据的方式。

3、字典(dict)的方式插入

1sql="insert into blog (author, context) values (%(author)s,%(context)s)"
2date={'author':"361way",context:20000}
3cursor.execute(sql,data)

对比元组的插入方式,可以看到两者在操作方式上基本上没什么区别,不同的是这里通过在占用符中间加入了键值 ,后面通过键值对的对应,将数据插入mysql 中。

4、列表(list)方式的插入

除了上面3种插入方式外,MySQLdb还支持通过列表(list)的方式进行插入,其和上面三种插入方式一个比较不同的地方是,其多用在多次插入中,相对于多次单次插入可以明显提高效率。

1sql="insert into blog (author, context) values (%s,%s)"
2date=[
3('361way',10000),
4('admin','361way is the best site'),
5('admin',20000)]
6cursor.executemany(sql,data)

三、MySQLdb 插入变量的问题

该问题是上面第二点中的一个问题,除了上面四种数据插入方式,sql 后面的占用符的值还支持直接插入--- %号与逗号连接方式,

1、%号连接

如:

1var_a="361way"
2var_b=10000
3sql="insert into blog (author, context) values (%s,%s)" %(var_a,var_b)
4cursor.execute(sql)

这里后面直接加了一个%号进行处理,不过在使用%号时有一个问题,就是不会自动转义。如我有一个如下的内容变量:

python连接mysql 的方案有oursqlPyMySQLmyconnpyMySQL Connector 等,不过本篇要说的确是另外一个类库MySQLdb,MySQLdb 是用于Python链接Mysql数据库的接口,它实现了 Python 数据库 API 规范 V2.0,基于 MySQL C API 上建立的。可以从:https://pypi.python.org/pypi/MySQL-python 进行获取和安装,而且很多发行版的linux源里都有该模块,可以直接通过源安装。

这时如果使用%号进行插入时,会遇到类似下面的错误:

1Traceback (most recent call last):
2  File "split.py", line 69, in cursor.execute(sql)
3  File "/usr/lib64/python2.6/site-packages/MySQLdb/cursors.py", line 173, in execute
4    self.errorhandler(self, exc, value)
5  File "/usr/lib64/python2.6/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
6    raise errorclass, errorvalue
7_mysql\_exceptions.ProgrammingError: (1064, 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '

解决该问题,有两种办法,一种,使用上面将变量值放入元组、字典或列表中,通过在cursor.execute后面加入data参数的方式插入数据,或者通过使用自动转义的逗号处理。

2、逗号连接

这里有很多特别字符需要转义处理,我们不可能一个个手动去处理,这时可以用逗号进行处理。假设上面的内容是变量var_b获取的内容,上面的写法将变成:

1sql="insert into blog (author, context) values (%s,%s)" ,(var_a,var_b)
2cursor.execute(*sql)

注意这里在sql 前加了*,%号换成了逗号。如果sql前不加*会报下面的错误:

1Traceback (most recent call last):
2  File "split.py", line 69, in
3    cursor.execute(sql)
4  File "/usr/lib64/python2.6/site-packages/MySQLdb/cursors.py", line 168, in execute
5    self.errorhandler(self, TypeError, m)
6  File "/usr/lib64/python2.6/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
7    raise errorclass, errorvalue
8TypeError: query() argument 1 must be string or read-only buffer, not tuple

逗号与%号的问题参考页面:](https://blog.361way.com/tag/CentOS)

python MySQLdb中转义字符串的问题

stackoverflow问题站