【问题标题】:ValueError: Cannot convert identifier to UTF-8: 'Id'ValueError:无法将标识符转换为 UTF-8:'Id'
【发布时间】:2015-10-08 14:18:16
【问题描述】:

我有一个大型 Pandas 数据框(超过 200 万行),包含以下列:

Id,CandidateRegistrationID,CandidateID,OurReference,QualificationCode,ExamCode,ExamDate,QualificationName,DataSource,QuestionNo,CandidateResponse,CorrectAnswerChoice,UniquePaperNo,QuestionCode

我有一个函数可以将数据帧写入 sqlite:

def writeDF(df,db,table):
    conn = sqlite3.connect(db)
    conn.text_factory = str  # allows utf-8 data to be stored

    df.to_sql(table, conn, flavor='sqlite', schema=None, if_exists='replace', index=False, index_label=None, chunksize=None, dtype=None)

    conn.close()

在数据的缩减版本上,这可以正常工作。在完整的数据集上,我收到以下错误:

ValueError: Cannot convert identifier to UTF-8: 'Id'

Id 字段只是一个整数。

我欢迎任何见解。谷歌搜索只会将我带到 Pandas 中出错的那一行。

Traceback (most recent call last):
File "/py-csv-jmetrik/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
  return self.wsgi_app(environ, start_response)
File "/py-csv-jmetrik/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
  response = self.make_response(self.handle_exception(e))
File "/py-csv-jmetrik/venv/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
  reraise(exc_type, exc_value, tb)
File "/py-csv-jmetrik/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
  response = self.full_dispatch_request()
File "/py-csv-jmetrik/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
  rv = self.handle_user_exception(e)
File "/py-csv-jmetrik/venv/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
  reraise(exc_type, exc_value, tb)
File "/py-csv-jmetrik/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
  rv = self.dispatch_request()
File "/py-csv-jmetrik/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
  return self.view_functions[rule.endpoint](**req.view_args)
File "/py-csv-jmetrik/app/routes.py", line 69, in index
  writeDF(data_df,db,table)
File "/py-csv-jmetrik/app/routes.py", line 27, in writeDF
  df.to_sql(table, conn, flavor='sqlite', schema=None, if_exists='replace', index=True, index_label=None, chunksize=None, dtype=None)
File "/py-csv-jmetrik/venv/lib/python2.7/site-packages/pandas/core/generic.py", line 982, in to_sql
  dtype=dtype)
File "/py-csv-jmetrik/venv/lib/python2.7/site-packages/pandas/io/sql.py", line 549, in to_sql
  chunksize=chunksize, dtype=dtype)
File "/py-csv-jmetrik/venv/lib/python2.7/site-packages/pandas/io/sql.py", line 1565, in to_sql
  dtype=dtype)
File "/py-csv-jmetrik/venv/lib/python2.7/site-packages/pandas/io/sql.py", line 627, in __init__
  self.table = self._create_table_setup()
File "/py-csv-jmetrik/venv/lib/python2.7/site-packages/pandas/io/sql.py", line 1377, in _create_table_setup
  for cname, ctype, _ in column_names_and_types]
File "/py-csv-jmetrik/venv/lib/python2.7/site-packages/pandas/io/sql.py", line 1297, in _get_valid_sqlite_name
  uname = _get_unicode_name(name)
File "/py-csv-jmetrik/venv/lib/python2.7/site-packages/pandas/io/sql.py", line 1271, in _get_unicode_name
  raise ValueError("Cannot convert identifier to UTF-8: '%s'" % name)

【问题讨论】:

  • stackoverflow.com/questions/3425320/… 问题看起来与此类似,但我不认为它是重复的。但它的答案(使用sqlite3.Binary 作为text_factory)可能与OP 的问题有关。值得一看。
  • @rmunn 我不确定,因为stackoverflow.com/questions/3425320/… 指的是存储 blob。我所做的只是存储文本字符串和数字。
  • 不,你是对的,这不是你遇到的问题。您遇到的情况是 column name “Id”无法转换为 Unicode。这很奇怪:当我查看pandas/io/sql.py 的源代码时,我看不出它应该失败的任何原因。

标签: python sqlite pandas


【解决方案1】:

也许你的问题有点晚了,但可以帮助其他程序员,我遇到了和你完全相同的问题,我正在使用 pandas 读取 csv,然后尝试在 bd sqlite 上插入。

对我有用的解决方案是在读取 csv 文件时声明结尾关键字:

import pandas as pd
import sqlite3
conn = sqlite3.connect('dbpath', isolation_level= None, check_same_thread=False)
df = pd.read_csv('csvfile.csv', encoding = "UTF-8-sig")
df.to_sql('tablename', con=conn, if_exists= 'append')

【讨论】:

    【解决方案2】:

    乍一看,我看不出为什么会发生这种情况。这是 Pandas 中抛出您所看到的错误的函数:

    def _get_unicode_name(name):                                                    
        try:                                                                        
            uname = name.encode("utf-8", "strict").decode("utf-8")                  
        except UnicodeError:                                                        
            raise ValueError("Cannot convert identifier to UTF-8: '%s'" % name)     
        return uname                                                                
    

    失败的唯一方法是如果将字符串“Id”编码为 UTF-8 失败,或者解码该 UTF-8 字符串失败。而且我看不到任何应该导致失败的名称“Id”。

    试试这个。由于您使用的是解释性语言 Python,因此请利用这一事实并编辑您正在使用的库的源代码。编辑/py-csv-jmetrik/venv/lib/python2.7/site-packages/pandas/io/sql.py,把上面的函数改成:

    def _get_unicode_name(name):                                                    
        try:                                                                        
            utf8name = name.encode("utf-8", "strict")
        except UnicodeError:                                                        
            raise ValueError("Cannot encode identifier to UTF-8: '%s'" % utf8name)     
        try:                                                                        
            uname = utf8name.decode("utf-8")                  
        except UnicodeError:                                                        
            raise ValueError("Cannot decode UTF-8: '%s'" % utf8name)     
        return uname                                                                
    

    这至少会告诉你这两个操作中的哪一个失败了。然后按如下方式运行你的程序:

    python myscript.py >stdout.txt 2>stderr.txt
    

    然后通过显微镜查看 stderr.txt(即将最后几行或前几行传送到 xxd)以查看其中的字符值:

    head -n 2 stderr.txt | xxd
    tail -n 2 stderr.txt | xxd
    

    您要做的是捕获带有 ValueError 的行,它会为您提供导致错误的标识符的名称(在本例中为“Id”)。查看您的“Id”标识符中是否有任何奇怪的字符,例如零宽度空格或类似的东西。这是我现在唯一能想到的。这可能没有帮助,但至少它会缩小问题的范围......也许吧。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-03
      • 2011-06-25
      • 1970-01-01
      • 2022-10-13
      • 2013-03-02
      • 1970-01-01
      相关资源
      最近更新 更多