【问题标题】:Encoding troubles with python, mysql and utf8mb4python、mysql和utf8mb4的编码问题
【发布时间】:2019-01-21 12:00:26
【问题描述】:

在尝试将简单数据框保存到 mysql 时,我收到以下警告:

C:...\anaconda3\lib\site-packages\pymysql\cursors.py:170: 警告: (1366, "Incorrect string value: '\x92\xE9t\xE9)' for column 'VARIABLE_VALUE' at第 518 行") 结果 = self._query(查询)

C:...anaconda3\lib\site-packages\pymysql\cursors.py:170:警告: (3719, "'utf8' 当前是字符集 UTF8MB3 的别名, 但在未来版本中将成为 UTF8MB4 的别名。请考虑 使用 UTF8MB4 以便明确。") 结果 = self._query(查询)

环境信息:我使用Mysql8,python3.6(pymysql 0.9.2,sqlalchemy 1.2.1)

我访问了类似下面链接的帖子,但似乎都没有给出如何避免此警告的解决方案。

注意:mysql 中表中的排序规则似乎没有设置为我在 Connection 类中的 create_db 函数中指定的排序规则。

可执行代码:

import DataEngine.db.Connection as connection
import random
import pandas as pd

if __name__ == "__main__":
    conn = connection.Connection(host="host_name", port="3306", user="username", password="password")
    conn.create_db("raw_data")
    conn.establish("raw_data")
    l1 = []
    for i in range(10):
        l_nested = []
        for j in range(10):
            l_nested.append(random.randint(0, 100))
        l1.append(l_nested)
    df = pd.DataFrame(l1)

    conn.save(df, "random_df")
    df2 = conn.retrieve("random_df")
    print(df2)

所以数据库中持久化的数据框是:

   index   0   1   2   3   4   5   6   7   8   9
0      0  11  57  75  45  81  70  91  66  93  96
1      1  51  43   3  64   2   6  93   5  49  40
2      2  35  80  76  11  23  87  19  32  13  98
3      3  82  10  69  40  34  66  42  24  82  59
4      4  49  74  39  61  14  63  94  92  82  85
5      5  50  47  90  75  48  77  17  43   5  29
6      6  70  40  78  60  29  48  52  48  39  36
7      7  21  87  41  53  95   3  31  67  50  30
8      8  72  79  73  82  20  15  51  14  38  42
9      9  68  71  11  17  48  68  17  42  83  95

我的Connection class

import sqlalchemy
import pymysql
import pandas as pd


class Connection:
    def __init__(self: object, host: str, port: str, user: str, password: str):
        self.host = host
        self.port = port
        self.user = user
        self.password = password
        self.conn = None

    def create_db(self: object, db_name: str, charset: str = "utf8mb4", collate:str ="utf8mb4_unicode_ci",drop_if_exists: bool = True):
        c = pymysql.connect(host=self.host, user=self.user, password=self.password)
        if drop_if_exists:
            c.cursor().execute("DROP DATABASE IF EXISTS " + db_name)
        c.cursor().execute("CREATE DATABASE " + db_name + " CHARACTER SET=" + charset + " COLLATE=" + collate)
        c.close()
        print("Database %s created with a %s charset" % (db_name, charset))

    def establish(self: object, db_name: str, charset: str = "utf8mb4"):
        self.conn = sqlalchemy.create_engine(
            "mysql+pymysql://" + self.user + ":" + self.password + "@" + self.host + ":" + self.port + "/" + db_name +
            "?charset=" + charset)
        print("Connection with database : %s has been established as %s at %s." % (db_name, self.user, self.host))
        print("Charset : %s" % charset)

    def retrieve(self, table):
        df = pd.read_sql_table(table, self.conn)
        return df

    def save(self: object, df: "Pandas.DataFrame", table: str, if_exists: str = "replace", chunksize: int = 10000):
        df.to_sql(name=table, con=self.conn, if_exists=if_exists, chunksize=chunksize)

一些可能有帮助的元素:

【问题讨论】:

    标签: mysql python-3.x character-encoding sqlalchemy pymysql


    【解决方案1】:

    嗯,十六进制 92 和 e9 不是有效的 utf8mb4 (UTF-8)。也许您期待’été,假设CHARACTER SETs cp1250、cp1256、cp1257 或latin1。

    找出该文本的来源,然后确定它是否有效latin1那么我们可以修改代码来声明客户端真的使用的是latin1,而不是utf8mb4?或者我们可以修复客户端使用 UTF-8,从长远来看可能会更好。

    【讨论】:

    • 但是没有éé,它们只是主要显示的数字。
    • @Aetos - 是法语,在谈论“夏天”吗?
    • 数据集中完全没有字符。如果数据不在数据集中,它还会来自哪里?
    • @Aetos - “第 518 行的列‘VARIABLE_VALUE’”——嗯……这是全新安装的 MySQL 吗?还是升级?请提供 SHOW VARIABLES;SHOW GLOBAL STATUS; 我想知道其中第 518 行是什么。
    • 这是全新安装。我做了一个mysql -u"UserName" -p -h "HOST" -A -e"SHOW GLOBAL STATUS;" > MySQLCurrentStatus.txt,我得到了一个 429 行的输出。至于SHOW GLOBAL STATUS;,第518行包含sync_relay_log_info 10000
    猜你喜欢
    • 2013-07-04
    • 2017-07-10
    • 2014-02-26
    • 2015-05-25
    • 2016-07-09
    • 2021-10-29
    • 2013-04-25
    • 1970-01-01
    • 2018-08-20
    相关资源
    最近更新 更多