首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ponyORM:查询的麻烦

ponyORM:查询的麻烦
EN

Stack Overflow用户
提问于 2014-04-21 18:59:25
回答 2查看 1.6K关注 0票数 3

我有动态条件的查询,即

代码语言:javascript
复制
select (lambda obj:obj.A = 'a' and obj.B = 'b' and ...)  

因此,我编写了以下代码:

代码语言:javascript
复制
def search(self,**kwargs):
        q = unicode('lambda obj:', 'utf-8')
    for field,value in kwargs.iteritems():
            value = unicode(value, 'utf-8')
            field = unicode(field, 'utf-8')
            q+=u" obj.%s == '%s' and" % (field,value

    q = q[0:q.rfind('and')] 
    res = select(q.encode('utf-8'))[:]

但是,在函数执行过程中出现了以下错误:

代码语言:javascript
复制
 tasks.search(title='Задача 1',url='test.com')
 res = select(q.encode('utf-8'))[:]
 File "<string>", line 2, in select
 File ".../local/lib/python2.7/site-packages/pony/utils.py", line 96, in      cut_traceback
return func(*args, **kwargs)
  File ".../local/lib/python2.7/site-packages/pony/orm/core.py", line 3844, in select
if not isinstance(tree, ast.GenExpr): throw(TypeError)
  File "...local/lib/python2.7/site-packages/pony/utils.py", line 123, in throw
  raise exc
  TypeError
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-22 17:44:07

虽然可以使用字符串来将条件应用于查询,但由于SQL注入的风险,它可能是不安全的。将条件应用于查询的更好方法是使用filter()方法。您可以从https://github.com/ponyorm/pony存储库中获取Pony的最新版本,并尝试下面提供的几个示例。

首先,我们定义实体并创建几个对象:

代码语言:javascript
复制
from decimal import Decimal
from pony.orm import *

db = Database('sqlite', ':memory:')

class Product(db.Entity):
    name = Required(unicode)
    description = Required(unicode)
    price = Required(Decimal)
    quantity = Required(int, default=0)

db.generate_mapping(create_tables=True)

with db_session:
    Product(name='iPad', description='Air, 16GB', price=Decimal('478.99'), quantity=10)
    Product(name='iPad', description='Mini, 16GB', price=Decimal('284.95'), quantity=15)
    Product(name='iPad', description='16GB', price=Decimal('299.00'), quantity=10)

现在,我们将应用筛选器,将它们作为关键字参数传递:

代码语言:javascript
复制
def find_by_kwargs(**kwargs):
    q = select(p for p in Product)
    q = q.filter(**kwargs)
    return list(q)

with db_session:
    products = find_by_kwargs(name='iPad', quantity=10)
    for p in products:
        print p.name, p.description, p.price, p.quantity

另一种选择是使用lambda来指定条件:

代码语言:javascript
复制
def find_by_params(name=None, min_price=None, max_price=None):
    q = select(p for p in Product)
    if name is not None:
        q = q.filter(lambda p: p.name.startswith(name))
    if min_price is not None:
        q = q.filter(lambda p: p.price >= min_price)
    if max_price is not None:
        q = q.filter(lambda p: p.price <= max_price)
    return list(q)

with db_session:
    products = find_by_params(name='iPad', max_price=400)
    for p in products:
        print p.name, p.description, p.price, p.quantity

如您所见,过滤器可以动态应用。您可以在下面的链接中找到有关使用过滤器的更多信息:http://doc.ponyorm.com/queries.html#Query.filter

票数 6
EN

Stack Overflow用户

发布于 2014-06-07 00:11:46

如果仍然希望使用字符串进行筛选,则必须为每个键/值对应用新的筛选器。

就像这样:

代码语言:javascript
复制
def search(self,**kwargs):
    q = select(m for m in Product)
    for field,value in kwargs.iteritems():
        value = unicode(value, 'utf-8')
        field = unicode(field, 'utf-8')
        flt = u"m.{0} == {1}".format(value, field)
        q = q.filter(flt)
    # return q # return Query which can be further modified (for ex. paging, ordering, etc.)
    return q[:] # or return found products

HTH,Tom

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23203960

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档