Python Sqlite3无法正确查询UTF-8字符串?

Python Sqlite3无法正确查询UTF-8字符串?,python,encoding,sqlite,Python,Encoding,Sqlite,我在使用带有UTF-8字符串的python sqlite3库时遇到了很多问题。我需要这种编码,因为我在数据库中处理人们的名字 所需表的SQL架构为: CREATE TABLE senators (id integer, name char); 我想在Python中执行以下操作(忽略我编写select语句的丑陋方式。我这样做是为了调试): 行[0]是文件中具有此类型项的每一行的名称: Dário Berger,1 Edison Lobão,1 Eduardo Braga,1 虽然像Eduard

我在使用带有UTF-8字符串的python sqlite3库时遇到了很多问题。我需要这种编码,因为我在数据库中处理人们的名字

所需表的SQL架构为:

CREATE TABLE senators (id integer, name char);
我想在Python中执行以下操作(忽略我编写select语句的丑陋方式。我这样做是为了调试):

行[0]是文件中具有此类型项的每一行的名称:

Dário Berger,1
Edison Lobão,1
Eduardo Braga,1
虽然像Eduardo Braga这样的名字有一个非空的结果,但每当我的字符串有UTF-8字符时,我都会得到一个空结果

我已经检查过我的文件实际上是用UTF-8编码(Microsoft记事本)保存的。在Apple mac上的终端中,我使用sqlite3 shell中的PRAGMA命令检查编码:

sqlite> PRAGMA encoding;
UTF-8
有人知道我在这里能做什么吗

编辑-完整示例: 创建数据库并使用senators.csv()中的初始数据填充的Python脚本:

使用Q1.txt()填充轮询表的脚本

如果要测试这些脚本,请注意文件路径。

来自:

重要提示:默认情况下,SQLite只理解ASCII字符的大小写。对于超出ASCII范围的unicode字符,LIKE运算符默认情况下区分大小写。例如,表达式
'a'LIKE'a'
为真,而
'æ'LIKE'Æ'
为假

另外,使用查询参数。您的查询易受SQL注入攻击。

好的,伙计们

在经历了很多麻烦之后,我发现问题在于编码虽然都被认为是UTF-8,但无论如何都是不同的。不同之处在于,当数据库被分解为UTF-8(ã=a+~)时,我的输入是预合成的形式(一个代码表示ã字符)

为了修复它,我必须将所有输入数据转换为分解的表单

 from unicodedata import normalize
 with open(poll, encoding='utf-8') as p:
        f_csv = csv.reader(p)
        for row in f_csv:
            name = normalize("NFD",row[0])
            c.execute(u'SELECT id FROM senators WHERE name LIKE ?', ('%'+name+'%',))

有关此主题的一些优秀信息,请参见此部分。

不要在SQL查询中使用字符串操作!看看Python文档中的大警告框,改用查询参数。@ColonelThirtyTwo我是用参数来做的,这只是为了调试以确保我在字符串插值中没有犯错误,因为我过去和现在都得到了奇怪的结果。请参阅我对@ColonelThirtyTwo关于查询参数的评论。这不是区分大小写的情况。当我复制数据库中的值时:例如,Sérgio Petecão,查询工作,但当我收到相同的字符串,显然编码略有不同,Sérgio Peteão,它就不工作了@jhc
选择像“%Edison Lobão%”一样的“Edison Lobão%”
为我返回1。请创建准确的架构、测试数据、查询和结果。请参阅我刚刚发布的编辑。
# -*- coding: utf-8 -*-
import sqlite3 
import csv

conn = sqlite3.connect('senators.db')
c = conn.cursor()
c.execute('''CREATE TABLE senators (id integer, name char)''')
c.execute('''CREATE TABLE polls (id integer, senator char, vote integer, FOREIGN KEY(senator) REFERENCES senators(name))''')

with open('senators.csv', encoding='utf-8') as f:
    f_csv = csv.reader(f)
    for row in f_csv:
        c.execute(u"INSERT INTO senators VALUES(?,?)", (row[1], row[0]))

conn.commit()
conn.close()
import csv
import sqlite3
import re
import glob

conn = sqlite3.connect('senators.db')
c = conn.cursor()

POLLS = {
    'senator': 'votes/senator/Q*.txt',
    'deputee': 'votes/deputee/Q*.txt',
}

s_polls = glob.glob(POLLS['senator'])
d_polls = glob.glob(POLLS['deputee'])

for poll in s_polls:
    m = re.match('.*Q(\d+)\.txt', poll)
    poll_id = m.groups(0)

    with open(poll, encoding='utf-8') as p:
        f_csv = csv.reader(p)
        for row in f_csv:
            c.execute(u'SELECT id FROM senators WHERE name LIKE ?', ('%'+row[0]+'%',))
            data = c.fetchone()
            print(data) # I should not get None results here, but I do, exactly when the query has UTF-8 characters.
 from unicodedata import normalize
 with open(poll, encoding='utf-8') as p:
        f_csv = csv.reader(p)
        for row in f_csv:
            name = normalize("NFD",row[0])
            c.execute(u'SELECT id FROM senators WHERE name LIKE ?', ('%'+name+'%',))