MySQL Connector/Python

来自百合仙子's Wiki
跳转到导航 跳转到搜索

一个 MySQL 官方维护的纯 Python 实现的 MySQL 库,但并不太成熟。推荐使用 pymysql

代码示例

#!/usr/bin/env python

import sys
from urllib.parse import urlsplit

import mysql.connector

from iris.util import shorten_company_name
from iris.settings import db_url

u = urlsplit(db_url)
login, host = u.netloc.split('@')
if ':' in host:
    host, port = host.split(':')
    port = int(port)
else:
    port = 3306
user, passwd = login.split(':')
db = u.path.strip('/')

conn = mysql.connector.connect(host=host, user=user, passwd=passwd, db=db, port=port)

def GetData():
    for l in sys.stdin:
        yield l, func(l)

c = conn.cursor()
try:
    for i, item in enumerate(GetData()):
        c.execute('''
                  insert ignore into table_name
                  (val1, val2) values (%s, %s)
                  ''', item)
        if i and i % 1000 == 0:
            print('%d...' % i)
    print('%d done.' % (i+1))
    conn.commit()
except:
    conn.rollback()
    raise
finally:
    conn.close()

让连接支持上下文管理

from mysql.connector.connection import MySQLConnection

def _conn_enter(self):
  return self.cursor()

def _conn_exit(self, exc_type, exc_value, traceback):
  if exc_type is not None:
    self.rollback()
    return False
  else:
    self.commit()
    return True

MySQLConnection.__enter__ = _conn_enter
MySQLConnection.__exit__ = _conn_exit

注意事项

二进制字面量作为列值

MySQL Connector/Python 中需要重命名列名,否则会尝试将二进制数据作为列名从而出错。需要在数据前添加binary字样来告诉 MySQL 这是二进制数据,如:

import mysql.connector
conn = mysql.connector.connect(host='lxc-debian', user='root', password='root', db='iris')
c = conn.cursor()
c.execute('select binary %s as a', (b'\xe0\xda\x94\xb8\x89\xf7\x14\xaa\xe0\x87D\xb9\xa6\x1b\xd6\n',))

二进制值作为参数

以下查询总是返回空结果,而不管数据库里有什么:

cursor.execute('select * from users where token = %s', (bytes_object,))

大的结果集

network.py:226行在「short recv」发生时直接报错:

mysql.connector.errors.InterfaceError: 2013: Lost connection to MySQL server during query

oursql 的区别

  • 连接对象不支持上下文管理(with语句)
  • 参数占位符使用%s而不是?
  • executemany的参数需要是 list 或者 tuple,而不是能任意 iterable
  • 可以使用multi=True来在一次调用中执行多条语句

参见

外部链接