使用python中的mysql连接器从mysql数据库正确获取blob
执行以下代码时:使用python中的mysql连接器从mysql数据库正确获取blob,python,mysql,mysql-connector-python,Python,Mysql,Mysql Connector Python,执行以下代码时: import mysql.connector connection = mysql.connector.connect(...) # connection params here cursor = connection.cursor() cursor.execute('create table test_table(value blob)') cursor.execute('insert into test_table values (_binary %s)', (np.ran
import mysql.connector
connection = mysql.connector.connect(...) # connection params here
cursor = connection.cursor()
cursor.execute('create table test_table(value blob)')
cursor.execute('insert into test_table values (_binary %s)', (np.random.sample(10000).astype('float').tobytes(),))
cursor.execute('select * from test_table')
cursor.fetchall()
我得到以下错误:
UnicodeDecodeError:“utf-8”编解码器无法在适当位置解码字节0xf7
1:起始字节无效
(…然后是一个堆栈跟踪,我认为它在这里没有用处)
似乎mysql连接器将我的blob转换为字符串(但没有成功)。如何在不进行任何转换的情况下将这些数据提取为字节?显然,这是Python“mysql”模块的一个已知问题。尝试改用“pymysql”。我们遇到了同样的问题,即在MySQL 8.0.13、MySQL connector python 8.0.13和sqlalchemy 1.2.14中,blob被错误地读回为UTF-8字符串 我们的诀窍是启用
use\u pure
。在8.0.11中,use\u pure
的默认值发生了变化,新的默认值是使用C扩展。因此,我们推迟了选项:
create_engine(uri, connect_args={'use_pure': True}, ...)
错误和堆栈跟踪的详细信息:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x9c in position 1: invalid start byte
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
....
File "/usr/local/lib/python3.6/site-packages/mysql/connector/cursor_cext.py", line 272, in execute
self._handle_result(result)
File "/usr/local/lib/python3.6/site-packages/mysql/connector/cursor_cext.py", line 163, in _handle_result
self._handle_resultset()
File "/usr/local/lib/python3.6/site-packages/mysql/connector/cursor_cext.py", line 651, in _handle_resultset
self._rows = self._cnx.get_rows()[0]
File "/usr/local/lib/python3.6/site-packages/mysql/connector/connection_cext.py", line 273, in get_rows
row = self._cmysql.fetch_row()
SystemError: <built-in method fetch_row of _mysql_connector.MySQL object at 0x5627dcfdf9f0> returned a result with an error set
UnicodeDecodeError:“utf-8”编解码器无法解码位置1中的字节0x9c:无效的开始字节
上述异常是以下异常的直接原因:
回溯(最近一次呼叫最后一次):
....
文件“/usr/local/lib/python3.6/site packages/mysql/connector/cursor_cext.py”,第272行,在execute中
自我处理结果(结果)
文件“/usr/local/lib/python3.6/site packages/mysql/connector/cursor\u cext.py”,第163行,在“handle\u result”中
self.\u handle\u resultset()
文件“/usr/local/lib/python3.6/site packages/mysql/connector/cursor_cext.py”,第651行,在_handle_resultset中
self.\u rows=self.\cnx.get\u rows()[0]
get_行中的文件“/usr/local/lib/python3.6/site packages/mysql/connector/connection_cext.py”,第273行
row=self.\u cmysql.fetch\u row()
SystemError:返回了一个带有错误集的结果
I再现了上述错误:
使用python代码
#!/usr/bin/python
# -*- coding: utf-8 -*-
import mysql.connector
conn = mysql.connector.connect(
user='asdf',
password='asdf',
host='1.2.3.4',
database='the_db',
connect_timeout=10)
cursor = conn.cursor(buffered=True) #error is raised here
try:
query = ("SELECT data_blob FROM blog.cmd_table")
cursor.execute(query, ())
except mysql.connector.Error as err: #error is caught here
#error is caught here, and printed:
print(err) #printed thustly
使用python的open(
如下所示:
$ python --version
Python 2.7.10
>>> mysql.connector.__version__
'8.0.15'
def read_file_as_blob(filename):
#r stands for read
#b stands for binary
with open(filename, 'rb') as f:
data = f.read()
return data
因此,问题在于文件中数据的编码转换->mysql blob的数据编码->和mysql如何提升该blob并将其转换回utf-8之间的某个地方
两种解决方案:
解决方案1与阿哈尔所说的一模一样,设置use_pure=True
参数并传递给mysql.connector.connect(…)
。然后神秘地工作。但好的程序员会注意到,遵从神秘的咒语是一种糟糕的代码味道。布朗运动的修复会招致技术债务
解决方案2是尽早并经常对数据进行编码,并防止双重重新编码和双重数据解码,这是这些问题的根源。请尽快将其锁定为通用编码格式
对我来说,令人满意的解决方案是在过程的早期强制使用utf-8编码。在任何地方强制使用utf-8
data.encode('UTF-8')
poo的unicode堆代表了我对在不同操作系统和编码方案上的不同设备之间进行字符编码的这种临时管理的看法。另一种方法是在连接初始化时使用
raw=True
参数:
connection = mysql.connector.connect(
host="localhost",
user="user",
password="password",
database="database",
raw=True
)
不得不
使用\u pure
,因为。但这对我没有帮助。似乎MySQL Python Connector中有一个bug,在使用准备好的语句时会破坏所有二进制字段。它只是坚持将它们作为某种编解码器进行解码。解决方法是(畏缩)更改为字符编码latin1
,它不能不解码。确实是一堆unicode poo。在注释下添加此类建议,而不是答案。
connection = mysql.connector.connect(
host="localhost",
user="user",
password="password",
database="database",
raw=True
)