pymysql
python连接mysql的驱动程序Pymysql,安装及一些常见的用法。对简单的操作,已提取封装成了一个库mysql_db。对遇到的问题,提出解决方案。
资源
安装
pip3 install pymysql
# 使用自定义源
pip2 install --trusted-host myweb.com -i http://myweb.com/pypi/simple/ pymysql
# 使用yum安装
yum install -y python2-PyMySQL.noarch
# python3.6 也可以, python36-PyMySQL.noarch
使用
三部曲
1打开
获取一个连接,获取一个cursor(游标),具体的操作,都是游标操作的。不同于其他语言的库,将所有的操作都绑定到cursor上。(其他语言,连接->查询获得 statement->从statement对象方法中获取具体的内容)
conn = pymysql.connect(host=host,port=port,user=user,password=password,database=database)
cursor = conn.cursor() #执行完毕返回的结果集默认以元组显示
cursor = conn.cursor( pymysql.cursors.DictCursor) #返回字典格式
cursor = conn.cursor(cursor = pymysql.cursors.DictCursor)
2操作
# 为了防止注入问题,直接使用 %s 代替,注意,跟sqllite3略有区别
sql = 'select * from test where title = %s'
cursor.execute(sql,params)
cursor.fetchall() # fetchone 一般查询的时候,这样操作 返回的
self.conn.commit() # 一般新增、更新的时候,需要提交,才会生效
3关闭
self.cursor.close()
self.conn.commit()
self.conn.close()
易错点
字段的包裹符号
pymysql.err.ProgrammingError: (1064, u’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 'year_month='{\“2021-09\“: 303, \“2021-08\“: 337, \“2020-09\“: 356, \“2020-11\“: ' at line 1’)
data = {'2021-09': 303, '2021-08': 337, '2020-09': 356, '2020-11': 197, '2020-10': 202, '2020-12': 136, '2021-01': 110, '2021-03': 240, '2021-02': 237, '2021-05': 256, '2021-04': 144, '2021-07': 269, '2021-06': 232, '2021-10': 287, '2021-11': 169, '2020-06': 21, '2020-08': 232, '2020-07': 203}
不知道为啥,可能是字符串中包含了特殊的哪内容,其他的字段都能插入,就这个字段不能插入。网上有人说:
pymysql.escape_string(dumps(data))
试了之后,多了几个反斜杆,还是报错。
终极解决方案:
# 如update 将所有的字段名称,用 ` ` 来包裹。 同理 insert
fields = ','.join(['`'+x+'`'+'=%s' for x in data.keys()])
即解决问题。
btw,pgsql是另外一种符号,即双引号包裹。
更新时,未触发更新时间
一般表,都会加id及下面的两个字段。下面的两个字段会在合适的触发条件加,触发。
`created_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
但是,我奇怪的是,虽然数据没有变化,调用了cursor.execute(sql,params),居然没有触发,更新updated_time字段。
port
注意,port必须是个整数类型。
conn = pymysql.connect(host=cfg[0],port=int(cfg[1]),user=cfg[2],password=cfg[3],database=cfg[4])
返回的数据
直接调用fetchall返回的数据,居然是个元组。需要自己的操作
未解决的问题
sql中如果出现了%d等类似的字符,本意是设置日期格式或者其他属于sql的部分,但是呢,易被误以为,要注入的参数?如何解决?
疑问:用问号???