尝试通过Python和Text文件将String插入MySQL时,“字符串值不正确”

时间:2016-10-04 21:33:24

标签: python mysql utf-8

导致这个错误字符串的原因是什么?我已经阅读了很多问题和答案,这是我的结果。读完答案后我仍然得到同样的错误。

我收到以下错误: ERROR 1366 (HY000) at line 34373: Incorrect string value: '\xEF\xBB\xBF<?x...' for column 'change' at row 1

当我尝试在SQL中输入以下内容时: 第34373行:INSERT INTO gitlog_changes VALUES ('123456', 'NhincCommonEntity.xsd', '<?xml version=\"1.0\" encoding=\"UTF-8\"?>');

我的表格如下:

DROP TABLE IF EXISTS `gitlog_changes`;
CREATE TABLE `gitlog_changes` (
  `hashID` varchar(40) NOT NULL,
  `filename` varchar(450) DEFAULT NULL,
  `change` mediumtext
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我读了许多答案,说将字符集更改为UTF8 [1] [2] [3] [4]。所以我执行这个: alter table yourTableName DEFAULT CHARACTER SET utf8;

我继续得到同样的错误。然后我alter table yourTableName DEFAULT CHARACTER SET utf8mb4_general_ci;

仍然发生同样的错误。

我还尝试从python中读取文件并直接提交到数据库。从这个答案[1]。我收到警告而不是错误。

我将以下代码插入到我的python脚本中:

    cursor.execute("SET NAMES 'utf8'")
    cursor.execute("SET CHARACTER SET utf8")

Python脚本:

def insert_changes(modList):
    db = MySQLdb.connect("localhost", "user", "password", "table")
    cursor = db.cursor()

    cursor.execute("SET NAMES 'utf8'")
    cursor.execute("SET CHARACTER SET utf8")

    for mod in modList:
        hashID = mod["hashID"]
        fileName = mod["fileName"]
        change = mod["change"]

        cursor.execute("INSERT INTO gitlog_changes VALUES (%s, %s, %s" , (hashID, fileName, change))
    # # disconnect from server
    db.commit()
    db.close()

我收到的警告是:Warning: Invalid utf8 character string: '\xEF\xBB\xBF<?x...' cursor.execute("INSERT INTO gitlog_changes VALUES (%s, %s, %s)" , (hashID, fileName, change))

2 个答案:

答案 0 :(得分:2)

您尝试插入的文字在开头包含UTF-8 BOM(错误中的 \ xEF \ xBB \ xBF )。

check this answer了解如何将带有BOM的UTF-8转换为UTF-8。

MySQL docs

中所述
  

MySQL对UTF-8值不使用BOM。

所以唯一的解决方案是在你的python代码中解码这个字符串。

答案 1 :(得分:2)

您尝试插入db的字符串在其开头有一个不寻常的字符。我刚刚复制了你的字符串:

public interface OperationFinalizerHook {
    void onOperationFinalize(Operation operation, Object context);
}
private final List<OperationFinalizerHook> operationFinalizeHooks = new ArrayList<>();
...
public void finalizeOperation(Object context) {
    final Operation operation = getOperation();
    operationFinalizeHooks.forEach(hook -> hook.onOperationFinalize(operation, context));
}

你需要摆脱那些角色。 This是一篇很好的文章,解释了这些角色是什么。