是否可以停止sqlite将双引号标识符视为字符串?

时间:2013-01-23 13:55:37

标签: python sql sqlite

根据:http://www.sqlite.org/draft/lang_keywords.html

如果你这样做,SQLite3会做你期望的事情:

select "foo" from bar;

但是,如果标识符不存在:

select "non-existant" from bar;

它将引用的文本视为字符串,后退(为了与旧版本兼容)。

这会给我带来麻烦,因为我使用这样的引用列动态创建查询,而后一种行为会返回无意义的结果而不是抛出错误。

我正在编写python代码,并使用包装PEP-249 Python数据库API规范v2.0模块的模块,因此我可以根据需要添加数据库特定的hacks。

我们的后端数据库可能会发生变化(事实上,在某些时候本地测试和生产可能会有所不同),所以我希望尽可能保持SQL本身的标准。

我有什么方法可以:

  • 停止/关闭此行为
  • 轻松/可靠地检测到这种情况已经发生(并提出我自己的例外,比如说)
  • 以某种方式解决这个问题(我不认为用非标准的等价物替换sql很容易以安全的方式以编程方式进行)

2 个答案:

答案 0 :(得分:2)

如果列名以表名或别名为前缀,则不能将它们误解为错误:

SELECT bar."foo", a."baz" FROM bar, blah AS a

当你处理多个表时,你可能需要使用它来避免列名冲突。

答案 1 :(得分:1)

请勿使用引号,请使用[]

sqlite> create table blah (name text);
sqlite> select "something" from blah;
sqlite> select "name" from blah;
sqlite> insert into blah values ('hello');
sqlite> select "something" from blah;
something
sqlite> select "name" from blah;
hello
sqlite> select [something] from blah;
Error: no such column: something
sqlite> select [name] from blah;
hello
sqlite> 

尝试以编程方式克服:

import re
from itertools import cycle

s = 'select "something" from blah;'
sel, cols, rest = re.match(r'(select)\s+(.*?)\s+(from\s+.*)', s).groups()
cols = re.sub('"', lambda g, I=cycle('[]'): next(I), cols)
print ' '.join( (sel, cols, rest) )
# select [something] from blah;