0

I am using PynamoDB and trying to genrate a dynamic query/scan on attributes from a flask request. Assuming the following model:

class Test(Model):
    class Meta:
        table_name = "test"
        region = "us-west-2"
    a = NumberAttribute(hash_key=True)
    b = NumberAttribute(range_key=True)
    c = UnicodeAttribute()

I have this bolted to Flask, so that when a user sends a request with query arguments such as ?a=123&b=456 I can turn this into a filter within PynamoDB to return results which match records with those two filters.

The following works for a single attribute:

>>> query = operator.eq(Test.a, 123)
>>> list(Test.scan(query))
[Test<4426599961>]

I am looking to be able to bolt this onto a dynamic number of attributes (beyond a,b and c for example)

I tried turning this into a tuple, but that seems to break with the following error:

>>> query = (operator.eq(Test.a, 123), operator.eq(Test.b, 456))
>>> list(Test.scan(*query))

but I get the following error:

Invalid type for parameter Segment, value: b = {'N': '1'}, type: <class 'pynamodb.expressions.condition.Comparison'>, valid types: <type 'int'>, <type 'long'>

Any ideas on how I can construct a dynamic filter to pass into the PynamoDB scan method?

2 Answers 2

2

How about:

q = { 'a': 123, 'b': 456 }

query = None
for fieldname in q:
    field = getattr(Test, fieldname, None)
    if field is None: continue
    clause = field == q[fieldname]
    query = clause if query is None else query & clause

print(list(Test.scan(cond)))    
Sign up to request clarification or add additional context in comments.

Comments

0

Have you tried:

query = (Test.a == 123) | (Test.b == 456)
list( Test.scan(query))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.