2014-02-07 38 views
4

我怎么做的方式是安全的SQLAclhemy ORM IN搜索不敏感的情况下?SQLAlchemy不区分大小写IN基于搜索查询?

我自己和其他人在我的项目已经看过了这一点,但我们不能似乎发现了什么适合我们的需要。

在原始的SQL我可以这样做:

SELECT * FROM TABLENAME WHERE UPPER(FIELDNAME) IN (UPPER('foo'), UPPER('bar')); 

..如果FOO和BAR都不在未知的情况下,用户的输入。正因为如此,我担心的是以下几点:

  1. 安全:我不想从鲍比表(http://xkcd.com/327/)在SQL注入的形式访问Attack.and我找不到,告诉我的文档如何在SQLAlchemy中转义字符串,或者我会觉得加入字符串更安全(但仍然觉得脏)。
  2. 速度的处理主要是通过索引,但显然,发出的查询会比告诉DB做得更快之前做的情况下更正内存,所以我不会去做上查询,除非我真的服了。然而,以上是展示我想要做什么的最佳方式。但是,它不应该做任何疯狂的事情。
  3. 平台无关的代码。我将在多个数据库类型运行这一点 - 它要进行全面的测试是我对此事的任何说 - 我不希望查询绑定到SQL的一个特定的对话框。毕竟,我为什么使用SQLAlchemy。 :)

如果有帮助,我们目前绑定到8.4版本的SQLAlchemy由于我们使用其他库。

回答

8

这应该编译正是...

query(models.Object)\ 
.filter( 
    sqlalchemy.func.upper(models.Object.fieldname)\ 
    .in_((sqlalchemy.func.upper(foo) , sqlalchemy.func.upper(bar),)) 
)\ 
.all() 

  1. 你也可以只通过在大写文字。亲自,我会做in_(foo.uppercase() , bar.uppercase())

  2. SqlAlchemy与DBAPI一起将绑定参数传递到后端数据存储中。翻译 - 值会自动转义。


,如果你想要做一个字符串列表,这样的事情应该工作

.in_([ i.upper() for i in inputs ]) 
.in_([ sqlalchemy.func.upper(i) for i in inputs ]) 

只是想补充一点,如果你想优化这些选择的速度,并且在Postgres或Oracle上,您可以创建一个'函数索引'

CREATE INDEX table_fieldname_lower_idx ON table(lower(fieldname)) 

查询规划器(在数据库中)将知道在使用lower(fieldname)查询进行搜索时使用lower(fieldname)索引。

+0

所以,如果我输入的是什么字符串列表? – honestduane

+0

我的第一篇文章使用了错误的语法。 in_期望可迭代。所以你可以抛出一个列表,list_comprehension,generator,lambda/map /等。 –

+1

将此设置为答案;我的团队和Bobby Table的母亲都非常感谢你。 – honestduane