这周上班,写了一个500多行的小脚本,跟精准广告投放有关,从线上的一些数据库中提取必要的数据,经过一些逻辑判断生成些新的数据,加一起放到自己这边的数据库里
过程中也是复制粘贴一路闪电带火花地无脑弄出很多sql语句,写完后觉得这代码要是改起来太蛋疼了,所以就想到了java里的hibernate做的类与表之间的ORM映射
下面总结一下心得:
① 在连接数据库的时候,设置cursorclass为MySQLdb.cursors.DictCursor是个不错的选择,当一个表有几十个字段的时候我才不想用数字来判断是哪个字段
import MySQLdb
import MySQLdb.cursors
conn = MySQLdb.connect(host="127.0.0.1", port=3306, user="root", passwd="root", db="test", cursorclass = MySQLdb.cursors.DictCursor)
cur = conn.cursor()
conn = MySQLdb.connect(host="127.0.0.1", port=3306, user="root", passwd="root", db="test")
cur = conn.cursor(cursorclass = MySQLdb.cursors.DictCursor)
sql = 'SELECT * FROM user'
cur.execute(sql)
res = cur.fetchone()
print res['userid'], res['username']
② 在完成①的设置后,我发现,由于python很温和,它不强求变量的类型,所以完全没必要手动定义变量、设置默认值
你只需要在连接数据库后,向每个表插入一次数据,得到的返回结果字典里,已经包含了所有字段名和他们的默认值
当然,别忘了删掉它
# 缺省uid,用于提取所有字段
DEFAULT_USERID = -32767
# 获取user初始值
def get_default_user():
sql = 'INSERT INTO user(userid) values(%d)'%DEFAULT_USERID
db.update(sql)
sql = 'SELECT * FROM auto.auto_user WHERE uid = %d'%DEFAULT_UID
global dct_user_default
dct_user_default = db.queryone(sql)
sql = 'DELETE FROM user WHERE userid = %d'%DEFAULT_UID
db.update(sql)
执行该方法,就会获得一个全局变量dct_user_default,它是一个包含所有字段名、默认值的字典,除了userid是你定义的缺省值
然后当new……好吧没有new,创建一个类对象时,deepcopy它一份,把userid之类的主键改掉即可
# user对应类
class obj_user(object):
def __init__(self):
# 获取默认字段与值
self.val = copy.deepcopy(dct_user_default)
# 设置主键userid
self.set('userid',userid)
def get(self,key):
if self.val.has_key(key):
return self.val[key]
else:
return None
def set(self, key, value):
self.val[key] = value
③ 接着,就是怎样将一个user类提交给数据库更新对应的数据了
正常来说这样的方法应该交给数据库操作类,而不是该类本身的行为……大概吧,不过我就爱写这你管我
# 插入用户信息
def insert_user(self):
# key_str是所有的字段名,以逗号分隔
key_str = ''
# val_str是所有的占位符,以逗号分隔
val_str = ''
# param是self.val中对应的值
param = []
for key in self.val:
key_str += key + ","
val_str += "%s,"
param.append(self.val[key])
sql = 'INSERT INTO user(%s) values(%s)'%(key_str[:-1],val_str[:-1])
db.update(sql,param)
这样就会在INSERT INTO auto.auto_user(%s)的%s部分自动填入所有的字段名,在valus(%s)部分填入足够的占位符
这是一个构造sql语句的过程,好处是你不需要劳心地去一个个手动填名字,排值的位置
update之类的语句也是同理,拼set后面的语句,字段名1=值2,字段名1=值2,...这样的
④ 完成③之后再回头看②,会发现一件事,dct_user_default根本就是多余的……
为什么?比如下面的代码:
user = obj_user('53723')
user.set('username','naoe')
user.insert_user()
set方法实际就是在字典里查找key,设置对应的value,没有这个key的话,会自动新建一个
而实际在insert或者update的时候,我们都是以指定字段名的方式操作的,指定哪些就更新哪些,其他字段会自动填入默认值
所以……其实并不需要get_default_user,当然作为一个获取字段名和默认值的办法,我觉得它还是挺棒的
总得来说,最花时间的地方还是理逻辑→提出不合理的地方→讨论→改数据库表的设计→改代码→理逻辑……这样一个循环
以及虐的我快要哭着找妈妈的编码问题,下次贴上来
其实这周挺闲的,写了个从视频生成终端下面的字符串动画的小脚本,就没几行代码,下次理一理也放上来
还想写个屏幕录制gif的,嘛,有空再说