环境描述:redhat4, mysql5.0
一.前期准备
1,升级redhat4的python,redhat4的版本是2.3的,太低了,不支持gbk编码。下载python2.5的源码包,解压后,进入安装文件目录,执行如下命令:
./configure --prefix=/usr/local/python25
make all
make install
ln -s /usr/ local/ python25/bin/python / usr/ bin/ python2.5
这里没有把python2.5作为默认的python,是考虑到redhat4中有些应用时依赖于低版本的python的,升级为高版本后可能会导致这些应用出错
2,安装mydel-client和mysql-devel,可以去mysql官网上去下rpm包安装。机器是64位的,我最初下了32位版本的,但是导致后面在安装mysql-python的时候出错,
下了64位的版本的安装就可以了。
3,安装setuptools,这个在安装mysql-python时需要,貌似现在很多安装包都需要这个。直接下载源码包,安装就行了,很简单。
4,安装mysql-python,前面的那些准备都做好后,这里就很easy了,直接编译源码包安装即可。
二出现的问题
1,时间转换问题。之间数据的日期格式是'2010-07-30 05:51:46',现在我们要把这些日期都保存成long值,由于我们的系统是用java开发的,这个值在java程序里是通过System.currentTimeMillis()来生成的,需要将日期导入成能被java程序正确转换的值。转换函数如下:
def totimestamp(dt):
stamp = mktime(dt.timetuple())
stamp = stamp*1000 + random.randint(0, 1000)
return stamp
日期格式在被mysql-python读出来后,会自动转换成datetime类型,省了不少事。
2,生成主键ID。由于是千万级的数据库,考虑了分库。为了防止主键冲突,我们所有的主键都是通过一个自己定义的mysql procedurel来运行的。该procedure定义如下
BEGIN
START TRANSACTION;
select last_value+1,last_value+cache_count
INTO oldValue,newValue
from dalsequence where name=seqName for update;
update dalsequence set last_value = last_value+cache_count where
name = seqName;
COMMIT;
END
生成主键的函数如下:
seq_map = {}
def get_primaryid(seqname):
seq_list = seq_map.get(seqname, None)
if seq_list and len(seq_list) >= 100:
return seq_list.pop(0)
if not seq_list:
seq_list = []
seq_map[seqname] = seq_list
cxn_seq = MySQLdb.connect(host="localhost", port=3306, user="root",
passwd="1111", db="idcenter")
cur_seq =cxn_seq.cursor()
a = '@oldValue'
b = '@newValue'
sql = "call getSequence('%s', %s, %s)"%(seqname, a, b)
cur_seq.execute(sql)
cur_seq.execute('select @oldValue, @newValue')
minid, maxid = cur_seq.fetchall()[0]
i = minid
while i<=maxid:
i = i + 1
seq_list.append(i)
cur_seq.close()
cxn_seq.close()
return seq_list.pop(0)
3,编码问题,原库是gbk编码,新库的utf-8编码。编码的语句如下:
des = data.decode('gbk', 'ignore').encode('utf8')
4,特殊字符(如/,'等)处理,之前不了解mysql-python对特殊字符的处理,自己处理特殊字符,但是试了好多方法都不太好使,因为特殊字符太多了,后来看了些资料,觉得mysql-python应该会有对特殊字符的处理,试了下,果然成功了。采用如下的方式,就会在插入数据时对数据自动做处理。
sql = "insert into fans (id, fassport, passport, created_at) values (%s, %s, %s, %s)"
cur_d.execute(sql, sqlargs)
注意这里必须用%s来做占位符,sqlargs是一个list,对应各个参数值
5,导数的时候用了Queue模块,启用连个线程,一个读,一个写。导完才想起来,应该试下multiprocess,应该能更充分利用下多核的优势。