【问题标题】:CSV to sqlite3 database.Convert list from Utf8 to unicodeCSV 到 sqlite3 数据库。将列表从 Utf8 转换为 unicode
【发布时间】:2011-10-27 16:11:04
【问题描述】:
import csv, sqlite3

conn = sqlite3.connect("mycustomers9.sql")
curs =  conn.cursor()
try:
    curs.execute("CREATE TABLE t (unknown1 TEXT, county TEXT, businessName TEXT, address1 TEXT, city1 TEXT, zip1 INTEGER, phone1 INTEGER,Email1 TEXT, approvalstatus TEXT, date1 TEXT, date2 TEXT, typeofConstruct TEXT, typeofBiz TEXT, unknown2 TEXT, unknown3 TEXT, unknown4 TEXT, unknown5 TEXT, unknown6 TEXT,BizName2 TEXT,Address2 TEXT, City2 TEXT,Zip2 TEXT,Country2 TEXT,Phone2 TEXT,Email2 TEXT,Phone3 TEXT);")
except sqlite3.OperationalError:
    print "Table already exist"
with open('HR_plan_review.csv', 'rb') as infile:
    dr = csv.DictReader(infile, delimiter = ',')
    to_db = [(i["unknown1"], i['county'], i['businessName'], i['address1'], i['city1'], i['zip1'], i['phone1'], i['Email1'], i['approvalstatus'], i['date1'],i['date2'], i['typeofConstruct'], i['typeofBiz'], i['unknown2'], i['unknown3'], i['unknown4'], i['unknown5'], i['unknown6'], i['BizName2'], i['Address2'], i['City2'], i['Zip2'], i['Country2'], i['Phone2'], i['Email2'], i['Phone3']) for i in dr]

curs.executemany("INSERT INTO t (unknown1, county, businessName, address1, city1,zip1, phone1, Email1, approvalstatus, date1, date2,typeofConstruct, typeofBiz, unknown2, unknown3, unknown4,unknown5, unknown6,BizName2,Address2, City2,Zip2,Country2,Phone2,Email2,Phone3) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);", to_db)

to_db 返回一个以 utf-8 编码的列表,sqllite 数据库似乎要求格式化为 unicode。在运行上面的 sql 语句之前,如何将“to_db”列表转换为 unicode。以下是我运行上述代码时收到的错误消息。

sqlite3.ProgrammingError: 你不能使用 8 位字节串,除非 您使用可以解释 8 位字节串的文本工厂(例如 text_factory = str)。强烈建议您改为 将您的应用程序切换到 Unicode 字符串。

根据答案输入进行编辑

修改后的代码(如下)现在可以成功执行,但它不会将取自 csv 的值插入到数据库中。

import csv, sqlite3

conn = sqlite3.connect("mycustomers12.sql")
curs =  conn.cursor()
try:
    curs.execute(""" CREATE TABLE t (unknown1 TEXT, county TEXT, businessName TEXT, address1 TEXT, city1 TEXT, zip1 INTEGER, \n
    phone1 INTEGER,Email1 TEXT, approvalstatus TEXT, date1 TEXT, date2 TEXT, typeofConstruct TEXT, typeofBiz TEXT, unknown2 TEXT, \n
    unknown3 TEXT, unknown4 TEXT, unknown5 TEXT, unknown6 TEXT,BizName2 TEXT,Address2 TEXT, City2 TEXT,Zip2 TEXT,Country2 TEXT,\n
    Phone2 TEXT,Email2 TEXT,Phone3 TEXT);""")
except sqlite3.OperationalError:
    print "Table already exist"


infile = open('HR_plan_review.csv', 'rb') 
dr = csv.DictReader(infile, delimiter = ',')
keys=("unknown1", 'county', 'businessName', 'address1',
    'city1', 'zip1', 'phone1', 'Email1', 'approvalstatus',
    'date1','date2', 'typeofConstruct', 'typeofBiz', 'unknown2',
    'unknown3', 'unknown4', 'unknown5', 'unknown6', 'BizName2',
    'Address2', 'City2', 'Zip2', 'Country2', 'Phone2',
    'Email2', 'Phone3')
args=[tuple(key.decode('utf-8') for key in keys) for row in dr]
sql='INSERT INTO t ({f}) VALUES ({p})'.format(
    f=','.join(keys),
    p=','.join(['?']*len(keys)))
curs.executemany(sql, args)

【问题讨论】:

  • “不插入值”是什么意思?你有错误吗?我们无法复制您的示例,因为我们没有您的文件 - 至少粘贴几行内容将对试图帮助您的人有所帮助。随机猜测 - 你没有正确关闭连接,所以也许 .sql 文件实际上没有正确写入?
  • 当我运行上面的代码时,我希望它能够创建 sqlite 数据库;将从我提供的“mycustomers12.sql”的csv文件中检索到的值插入到适当的列中。它确实创建了数据库,但是以逗号分隔的值形式的值不会插入到代码中。它执行没有错误但没有任何错误但无法插入值。

标签: python sqlite


【解决方案1】:

遗憾的是,csv 无法处理 unicode(至少在 Python 2.7 中)。但是您可以通过将 DictReader 包装在生成器中来解决此问题:

with open('HR_plan_review.csv', 'rb') as infile:
    dr = csv.DictReader(infile, delimiter = ',')
    def unicoded_data():
        for row in dr:
            # Assuming infile encoding is utf-8.
            yield dict([(key, unicode(value, encoding='utf-8'))
                       for key, value in row.iteritems()])

    to_db = [(i["unknown1"], i['county'], i['businessName'], i['address1'], i['city1'], i['zip1'], i['phone1'], i['Email1'], i['approvalstatus'], i['date1'],i['date2'], i['typeofConstruct'], i['typeofBiz'], i['unknown2'], i['unknown3'], i['unknown4'], i['unknown5'], i['unknown6'], i['BizName2'], i['Address2'], i['City2'], i['Zip2'], i['Country2'], i['Phone2'], i['Email2'], i['Phone3']) for i in unicoded_data()]

【讨论】:

    【解决方案2】:
    keys=("unknown1", 'county', 'businessName', 'address1',
        'city1', 'zip1', 'phone1', 'Email1', 'approvalstatus',
        'date1','date2', 'typeofConstruct', 'typeofBiz', 'unknown2',
        'unknown3', 'unknown4', 'unknown5', 'unknown6', 'BizName2',
        'Address2', 'City2', 'Zip2', 'Country2', 'Phone2',
        'Email2', 'Phone3')
    args=[tuple(i[key].decode('utf-8') for key in keys) for row in dr]
    sql='INSERT INTO t ({f}) VALUES ({p})'.format(
        f=','.join(keys),
        p=','.join(['?']*len(keys)))
    curs.executemany(sql, args)
    

    或者,对于更强大的解决方案,您可以使用 UnicodeDictReader,UnicodeReader (from the csv docs) 的略微修改版本,将行作为具有 unicode 值的字典返回:

    class UTF8Recoder:
        """
        Iterator that reads an encoded stream and reencodes the input to UTF-8
        """
        def __init__(self, f, encoding):
            self.reader = codecs.getreader(encoding)(f)
    
        def __iter__(self):
            return self
    
        def next(self):
            return self.reader.next().encode("utf-8")
    
    class UnicodeDictReader:
        def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
            f = UTF8Recoder(f, encoding)
            self.reader = csv.DictReader(f, dialect=dialect, **kwds)
    
        def next(self):
            row = self.reader.next()
            return dict((key,unicode(val, "utf-8")) for key,val in row.iteritems())
    
        def __iter__(self):
            return self
    
    with open('HR_plan_review.csv', 'rb') as infile:
        dr = UnicodeDictReader(infile, delimiter = ',')
    

    我上面贴的代码还是可以用的,改一下就行了

    args=[tuple(i[key].decode('utf-8') for key in keys) for row in dr]
    

    args=[tuple(i[key] for key in keys) for row in dr]
    

    【讨论】:

    • 即使已经导入了 csv 模块。我得到“AttributeError:'module'对象没有属性'UnicodeDictReader'
    • 糟糕,我不应该写csv.UnicodeDictReader,因为我在脚本本身中定义了UnicodeDictReader。将其更改为UnicodeDictReader(不带csv.)。
    • 这是我得到的修改后的代码和输出错误。第一部分是修改后的代码,底部是输出错误。 pastebin.com/pzsznp1U
    【解决方案3】:

    你需要提交执行:

    conn.commit()
    

    你的executemany语句也应该放在“with”块内:

    import csv, sqlite3
    
    myfile = 'CSV FILE PATH'
    conn = sqlite3.connect("DBNAME.sqlite3")
    curs =  conn.cursor()
    try:
        curs.execute("CREATE TABLE t (webrank INTEGER, term, TEXT PRIMARY KEY, gloss TEXT);")
    except sqlite3.OperationalError:
        print "Table already exist"
    with open('{}.csv'.format(myfile), 'rb') as infile:
        dr = csv.DictReader(infile, delimiter = ',')
        def unicoded_data():
            for row in dr:
                # Assuming infile encoding is utf-8.
                yield int(row['WebRank']), unicode(row['term'], encoding='utf-8'), unicode(row['gloss'], encoding='utf-8')
    
        curs.executemany("INSERT INTO t (webrank, term, gloss) VALUES (?,?,?);", unicoded_data())
        conn.commit()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-12
      • 1970-01-01
      • 2021-11-15
      • 2017-02-24
      • 1970-01-01
      • 2017-06-20
      • 2013-06-06
      相关资源
      最近更新 更多