cityofaustin / knackpy

A Python client for interacting with Knack applications
https://cityofaustin.github.io/knackpy/docs/user-guide/
Other
39 stars 17 forks source link

Unable to make filters work #89

Closed elrezad closed 3 years ago

elrezad commented 3 years ago

Hi Team, thanks for your incredible work. I'm not sure if this is the place to ask for help, so please let me know if I should ask elsewhere.

I'm trying to update Knack's database with a csv file using your package. First I download Knack's db, compare it with the csv, and check for the differences. So far so good.

The problem is updating the records. I want to use one field, "Unique ID", to get the record to update, so I built this:

app=knackpy.App(app_id=appid, api_key=apikey)
for ind in list_of_ID_to_update:
     filtro = [{"field": "Unique ID", "operator": "is","value": id_to_update}]
     records=app.get("object_8", record_limit=1, filters=filtro)
     r2= [record.format() for record in records]

But it always returns the record with 'Unique ID'==1, no matter the value of id_to_update.

I've even tried using a filter that shouldn't return anything:

app=knackpy.App(app_id=appid, api_key=apikey)
filtro = {
        "match":"and",
        "rules":[
            {"field": "Unique ID", "operator": "is","value": 0},
            {"field": "CSL", "operator": "is","value": 'John Doe'}
            ]}
records=app.get("object_8", record_limit=1, filters=filtro)
r2= [record.format() for record in records]

and I always get the first record (or the first 10 records if I change the record_limit).

Any idea of what am I doing wrong? Thanks

elrezad commented 3 years ago

So... I'm now using Knack's internal name, so instead of using "field": "Unique ID" I'm using "field": "field_123"

And now it works. However, it only works once. If I make a second search, it returns the previous records:

# 1st filter, it returns the correct record
filtro1 = {
            "match":"and",
            "rules":[
                {"field": fieldID, "operator": "is","value": 2},
                {"field": fieldCSL, "operator": "is","value": 'John Doe'}
                ]}
records = app.get("object_8", record_limit=1, filters=filtro1)
r2= [record.format() for record in records] 
print(r2[0]['Unique ID']) # and it works!

# Now I use a filter with different values    
filtro2 = {
            "match":"and",
            "rules":[
                {"field": fieldID, "operator": "is","value": 4},
                {"field": fieldCSL, "operator": "is","value": 'Jane Jane'}
                ]}
records = app.get("object_8", record_limit=1, filters=filtro2)
r2= [record.format() for record in records]
rint(r2[0]['Unique ID']) 
# But it returns the previous record (filtro1)

I've tried adding a sleep(30) just in case it was a cache problem, but same result

The only way it works is by adding app=knackpy.App(app_id=appid, api_key=apikey) before each app.get.

johnclary commented 3 years ago

@elrezad thanks for reaching out. yes, this is a bit of a gotcha—App.get() will not re-fetch data unless you also pass in the refresh=True arg.

So, in your example:

records = app.get("object_8", record_limit=1, filters=filtro2, refresh=True)

This detail is not in the user guide, but it's documented in the API reference.

I'll be honest that I haven't tested this parameter since I wrote the code—let me know if you run into any issues.