本例用Python操纵MySQL,从指定文件读取数据,并对数据进行处理,处理之后批量插入MySQL。
贴上代码:
# -*- coding: gbk -*- import re import MySQLdb import time def select(sqlselect): try: conn = MySQLdb.connect("localhost","test","123456","testdb" ) cursor=conn.cursor() # 使用execute方法执行SQL语句 cursor.execute(sqlselect) # 使用 fetchone() 方法获取一条数据。 data = cursor.fetchone() #读取所有行 data = cursor.fetchall() return data except Exception,e: print e #print "Data from mysql: %s %s %s %s" %(data[0],data[1],data[2],data[3]) finally: # 关闭数据库连接 conn.close() def loadData(dataFile,rowlimts=0): #dataFile=r'E:cabspottingdata ew_abboip.txt' cabid=dataFile[dataFile.index('_')+1:dataFile.index('.')] myFile=open(dataFile,'r',2048)#2048为缓冲大小 newline=myFile.readline() records=[] splitter=re.compile('\s')#以空白字符作为分隔符 rows=0 if rowlimts>0: while newline and rows<rowlimts: content=splitter.split(newline) record=[] record.append(float(content[0])) record.append(float(content[1])) record.append(int(content[2]))#int型也可插入到数据库的bit型字段 dt=time.gmtime(int(content[3]))#将unix时间,如1213084687,转换成time类型 dtStr=time.strftime('%Y-%m-%d %H:%M:%S',dt)#将time对象,格式化为"2008-06-10 07:58:07"型字符串 record.append(dtStr) record.append(cabid) records.append(record) rows+=1 newline=myFile.readline() else: while newline: content=splitter.split(newline) record=[] record.append(float(content[0])) record.append(float(content[1])) record.append(int(content[2])) dt=time.gmtime(int(content[3])) dtStr=time.strftime('%Y-%m-%d %H:%M:%S',dt) record.append(dtStr) record.append(cabid) records.append(record) newline=myFile.readline() myFile.close() return records def insertItems(records): if len(records)>0: #注意,不论MySQL的表结构中,某个字段为何种类型,Python的SQL语句中都要用%s来表示格式 sql="insert into geoinfo(latitude,longitude,occupancy,time,cabid)values(%s,%s,%s,%s,%s)" values=[] for record in records: values.append((record[0],record[1],record[2],record[3],record[4])) try: conn = MySQLdb.connect("localhost","test","123456","testdb" ) _cursor=conn.cursor() #批量插入 _cursor.executemany(sql,values) conn.commit()#Insert和update操作必须调用commit方法,操作才能生效 return 0 except Exception,e: raise e return -1 finally: conn.close() def insertItem(record): if record!=None: #注意,不论MySQL的表结构中,某个字段为何种类型,Python的SQL语句中都要用%s来表示格式 sql="insert into geoinfo(latitude,longitude,occupancy,time,cabid)values(%s,%s,%s,%s,%s)" sql=sql%(record[0],record[1],record[2],record[3],record[4]) try: conn = MySQLdb.connect("localhost","test","123456","testdb" ) _cursor=conn.cursor() _cursor.execute(sql) conn.commit() return 0 except Exception,e: raise e return -1 finally: conn.close() if __name__=='__main__': dataFile=r'E:cabspottingdata ew_abboip.txt' records=loadData(dataFile) print 'inserting %d records'%len(records) insertItems(records) data=select("select objectid from geoinfo limit 0,10")#查询前10条 print data print 'inserting completed.'
注意事项:
1)批量插入时,cursor.execute()放在for循环中的执行,其效率远不如cursor.executemany()方法。
2)不论MySQL的表结构当中,某个字段为何种类型,如float,int,bit,datetime型, Python的SQL语句中都要用%s来表示格式,否则对于非字符串类型的字段,插入式可能会报错。
例如,我在插入geoinfo表(结构如下,objectid字段为自增长)时,当插入语句写成 sql="insert into geoinfo(latitude,longitude,occupancy,time,cabid)values(%f,%f,%d,%s,%s)" 时会报错:
"float argument required, not str"
后来改成 sql="insert into geoinfo(latitude,longitude,occupancy,time,cabid)values(%s,%s,%s,%s,%s)" 就没错了。
另外,对于37.75134和-122.39488这样的小数型,若字段设计为float型时,插入时,MySQL会自动将其截断,并作四舍五入,
我以为是长度不够,于是改长度为50,插入时却被自动截断为整数,后改成double型才可以。