通过Python将数据从MySQL迁移到MongoDB - Unicode字符串错误

0 投票
1 回答
1101 浏览
提问于 2025-04-17 22:57

我在一个MongoDB集合中存储Google云消息的设备令牌。

我遇到的问题是,我的数据集中有一个设备令牌(是从MySQL迁移过来的)包含了\x87\,而Python的Mongo驱动把它当作ASCII码来读取,因此给我报了错:bson.errors.InvalidStringData: strings in documents must be valid UTF-8: ...

有没有办法让Python的驱动忽略这个ASCII码,直接把它当作字符字符串来读取,而不需要做一些麻烦的事情,比如转义反斜杠?

因为这个令牌是由Google的SDK生成的有效令牌,所以以后可能还会出现类似的情况,我不想丢失令牌。如果可以的话,我也不想在从数据库中选择令牌时进行任何操作,因为我一次会提取几百万个令牌,这样会增加加载令牌的时间。

下面是我如何构建要添加到MongoDB的文档的示例:

for row in rows: # rows coming from an existing MySQL databse table
    rows_out.append({
        'token_id': row['token_id'],
        'token_string': row['token_string'],
        'token_added': row['token_update'],
        'token_platform': 'D',
        'token_update': 0,
        'update_count': 0,
        'user_country': 'uk'
    })

任何帮助都将不胜感激,谢谢!

编辑:

从MySQL加载令牌并转存到MongoDB

def create_insert(rows):
    rows_out = []
    for row in rows:
        rows_out.append({
            'token_id': row['token_id'],
            'token_string': row['token_string'],
            'token_added': row['token_update'],
            'token_platform': 'D',
            'token_update': 0,
            'update_count': 0,
            'user_country': 'uk'
        })

    return rows_out

while True:
    cur = mysql.cursor()
    assert isinstance(cur, DictCursor)

    cur.execute("""
    SELECT
      token_id,
      token_string,
      token_update
    FROM
      user_push_token
    LIMIT
      %d
    OFFSET
      %d
    """ % (SELECT_COUNT, tokens_done), None)
    rows = cur.fetchall()

    col.insert(create_insert(rows)) # pymongo collection cursor

    tokens_done += len(rows)
    if len(rows) < SELECT_COUNT:
        break

1 个回答

0

我不太确定能否完全解释你的问题,但我有个直觉,试试把这一行改成:

'token_string': row['token_string'],

改成:

'token_string': row['token_string'].encode("UTF-8"),

至少这样做可以更清楚地显示出问题发生的具体位置。

撰写回答