SQLAlchemy不区分大小写的基于搜索的查询?

时间:2014-02-07 23:34:00

标签: python mysql sql sqlalchemy pyramid

如何以安全的方式在SQLAclhemy ORM中进行不区分大小写的搜索?

我和我的项目中的其他人都在寻找这个,但我们似乎无法找到任何符合我们需求的东西。

在原始SQL中,我可以这样做:

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

..如果FOO和BAR在未知情况下不是用户输入。事实上,我担心以下情况:

  1. 安全性:我不希望以SQL注入攻击的形式访问Bobby Tables(http://xkcd.com/327/)。我找不到告诉我如何在SQLAlchemy中转义字符串的文档,或者我觉得更安全的连接字符串(但仍然感觉很脏)。
  2. 速度主要通过索引处理,但很明显,在发出查询之前在RAM中进行大小写修正比告诉DB更快,所以我不会在查询中执行UPPER,除非我真的不得不这样做。然而,上面是展示我想做的最佳方式。但是,它不应该做任何疯狂的事情。
  3. 平台无关的代码。我将在多种数据库类型上运行它 - 它将进行全面测试,我对此事有任何发言权 - 我不希望将查询绑定到SQL的特定对话框。毕竟,为什么我使用SQLAlchemy。 :)
  4. 如果它有帮助,由于我们使用其他库,我们目前已经绑定到8.4版本的SQLAlchemy。

1 个答案:

答案 0 :(得分:9)

这应该准确编译......

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一起将绑定参数传递到后端数据存储区。翻译 - 值会自动转义。


  3. 如果你想做一个字符串列表,这样的东西应该可以工作

    .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)索引。