【问题标题】:Python mysqlclient and data on two different serversPython mysqlclient 和两个不同服务器上的数据
【发布时间】:2020-02-01 19:17:18
【问题描述】:

在我的本地机器 (MacOS) 上,我有 MariaDB 10.4、Python 3.7.4 和 mysqlclient 1.4.4。 在远程服务器 (FreeBSD) 上,我有 MySQL 5.2、Python 3.7.2 和 mysqlclient 1.4.4。

数据库在两台机器上都采用utf8 编码。

我的脚本使用 CONCAT 查询,例如:

SELECT IF(agreements.date <> '0000-00-00', CONCAT(agreements.date, ' 00:00:00 +0300'), '').....

为什么在我的本地机器上,结果元组中的值始终是 STR,但在远程服务器上是 STRBYTES 并且每个我使用 mysql 的 CONCAT 函数的列值以 b'...' 开头并具有 BYTES 类。 我知道我可以解码字节值 (b.decode()) 并保持其他 str 值不变

data = cursor.fetchall()
l = [list(x) for x in data]
for d in l:
    for idx, vals in enumerate(d):
        if isinstance(vals, bytes):
            d[idx] = vals.decode()

但为什么会发生这种情况 - MySQL 版本??

我看到了两种方法:通过 Python 解码,或者使用 mysql 的 CONVERT &lt;column&gt; USING utf8 函数,正如 @Joe McKenna 所说。但是为什么我不应该在我不知道的本地计算机上执行此操作:( MySQL 服务器版本不同,但字符集配置相同。

示例脚本:

#!/usr/local/bin/python3
# coding: utf8


import MySQLdb

connection = MySQLdb.Connection(
    user='root',
    passwd='password',
    db='billing',
    host='localhost',
    charset='utf8'
)

cursor = connection.cursor()


cursor.execute("SELECT '', CONCAT(birthdate, ' TEST!!!!!') from accounts")
for d in cursor.fetchall():
    print(d)

cursor.close()
connection.close()

输出:

('', b'1958-11-11 TEST!!!!!')
('', b'0000-00-00 TEST!!!!!')
('', b'0000-00-00 TEST!!!!!')
('', b'0000-00-00 TEST!!!!!')
('', b'0000-00-00 TEST!!!!!')
('', b'0000-00-00 TEST!!!!!')
('', b'0000-00-00 TEST!!!!!')
('', b'0000-00-00 TEST!!!!!')
('', b'1950-10-09 TEST!!!!!')

更新:

mysql&gt; SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';的结果

本地主机:

+--------------------------+--------------------+
| Variable_name            | Value              |
+--------------------------+--------------------+
| character_set_client     | utf8               |
| character_set_connection | utf8               |
| character_set_database   | utf8               |
| character_set_filesystem | binary             |
| character_set_results    | utf8               |
| character_set_server     | utf8mb4            |
| character_set_system     | utf8               |
| collation_connection     | utf8_general_ci    |
| collation_database       | utf8_general_ci    |
| collation_server         | utf8mb4_general_ci |
+--------------------------+--------------------+

远程服务器:

+--------------------------+-----------------+
| Variable_name            | Value           |
+--------------------------+-----------------+
| character_set_client     | utf8            |
| character_set_connection | utf8            |
| character_set_database   | utf8            |
| character_set_filesystem | binary          |
| character_set_results    | utf8            |
| character_set_server     | utf8            |
| character_set_system     | utf8            |
| collation_connection     | utf8_general_ci |
| collation_database       | utf8_general_ci |
| collation_server         | utf8_general_ci |
+--------------------------+-----------------+

【问题讨论】:

    标签: python mysql unicode encoding


    【解决方案1】:

    在所有带有“convert”关键字的查询中嵌入输出类型,就像这篇文章一样:


    Convert output of MySQL query to utf8


    SELECT column1, CONVERT(column2 USING utf8) FROM my_table WHERE my_condition;


    或者您可以使用“alter”命令将数据库中的每一列更改为您想要的数据类型:


    https://dba.stackexchange.com/questions/33365/tell-mysql-to-start-using-utf-8-encoding-without-convert-toing-it


    【讨论】:

    • 感谢您的回答,但为什么我要转换输出?我的数据库已经在 utf8 中,表也在 utf8 中。如果我在没有 CONCAT 的情况下进行查询,我会得到正常数据。 CONCAT 函数是否返回二进制数据?如果是这样 - 为什么在 macOS 上它是字符串,而不是字节。附: CONVERT(column USING utf8) 当然可以。
    • mysql concat 函数的结果因参数数据类型而异,如下所示: *** • 返回连接参数的字符串。 • 如果所有参数都是非二进制字符串,则返回一个非二进制字符串。 • 如果参数包含任何二进制字符串,则返回二进制字符串。 • 如果参数是数字,则将其转换为其等效的非二进制字符串形式。 • 如果任何参数为NULL,则返回NULL。 *** 在“concat”之外添加“convert”可使返回数据类型更加一致。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多