我查询一个 API 并获得一个具有以下值的 json blob:
{
...
"Attribute" : "Some W\u00e9irdness",
...
}
(当然,正确的值是“Some Wéirdness”)
我将该值与其他一些东西一起添加到我想要添加到我的 sqlite3 数据库的字段列表中。该列表如下所示:
[None, 203, None, None, True, u'W\xe9irdness', None, u'Some', None, None, u'Some W\xe9irdness', None, u'Some W\xe9irdness', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]
我注意到我们已经经历了从 \x00e9 到 \xe9 的转换,我还不确定为什么会这样,但我希望这没关系......这只是一个不同的 unicode 编码。
在尝试插入 sqlite 表之前,我将列表“字符串化”(参见下面的函数)并将其设为元组:
('', '203', '', '', 'True', 'W\xe9irdness', '', 'Some', '', '', 'Some W\xe9irdness', '', 'Some W\xe9irdness', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '')
然后我进行插入:
my_tuple = tuple(val for val in my_utils.stringatize(my_list))
sql = "INSERT OR REPLACE INTO roster VALUES %s" % repr(my_tuple)
cur.execute(sql)
当我稍后使用 SELECT 语句检索它时,该值添加了一个额外的转义(反斜杠)字符:
u'Some W\\xe9irdness'
首先,我已经知道我不应该在 sqlite 中使用字符串插值。但是,当每条记录的字段数可能随时间变化时,我无法弄清楚如何使用?字段。(如果你知道更好的方法来做到这一点,我会全力以赴,但这可能是另一篇文章。)
为了排除故障,我打印了格式化的插入 sql 语句,我只看到一个反斜杠:
INSERT OR REPLACE INTO roster VALUES ('', '203', '', '', 'True', 'W\xe9irdness', '', 'Some', '', '', 'Some W\xe9irdness', '', 'Some W\xe9irdness', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '')
这与我在上面的列表中的显示方式相同,所以我很困惑。也许这被解释为带有必须转义的反斜杠的字符串,并且 xe9 只是被视为 ascii 文本。这是我用来准备插入列表的 stringatize 函数:
def stringatize(cell_list, encoding = 'raw_unicode_escape', delete_quotes = False):
"""
Converts every 'cell' in a 'row' (generally something extracted from
a spreadsheet) to a unicode, then returns the list of cells (with all
strings now, of course).
"""
stringatized_list = []
for cell in cell_list:
if isinstance(cell, (datetime.datetime)):
new = cell.strftime("%Y-%m-%dT%H:%M:%S")
elif isinstance(cell, (datetime.date)):
new = cell.strftime("%Y-%m-%d")
elif isinstance(cell, (datetime.time)):
new = cell.strftime("%H:%M:%S")
elif isinstance(cell, (int, long)):
new = str(cell)
elif isinstance(cell, (float)):
new = "%.2f" % cell
elif cell == None:
new = ""
else:
new = cell
if delete_quotes:
new = new.replace("\"","")
my_unicode = new.encode(encoding)
stringatized_list.append(my_unicode)
return stringatized_list
我很感激你在这方面对我的任何想法。目标是最终将此值转储到 Excel 工作表中,该工作表可以使用 Unicode,因此应该正确显示该值。
编辑:响应@CL 的询问,我尝试从我的字符串化函数中删除“编码”行。
现在结束如下:
#my_unicode = new.encode(encoding)
my_unicode = new
stringatized_list.append(my_unicode)
return stringatized_list
新的 sql 看起来像这样(下面是我尝试执行它时得到的回溯):
INSERT OR REPLACE INTO roster VALUES ('', u'203', u'', u'', 'True', u'W\xe9irdness', '', u'Some', '', '', u'Some W\xe9irdness', '', u'Some W\xe9irdness', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '')
Traceback (most recent call last):
File "test.py", line 80, in <module>
my_call
File redacted.py, line 102, in my_function
cur.execute(sql)
sqlite3.OperationalError: near "'203'": syntax error
我的意思是将该数字转换为字符串。我怀疑它与我正在做的 repr(my_tuple) 和 u'' 实际上不再象征着 unicode 有关。