-
Notifications
You must be signed in to change notification settings - Fork 38
Changes InteractionBase.select() to preserve where clause when id argument is provided #69
Conversation
This works as expected when an id is not provided to DBObject.find(where=...), but failed to work when using specifying an id DBObject.find(id, where=...). InteractionBase.select() discards the clause if an id is provided. This patch retains any provided where clause.
I recently ran into a use case (permissions checking in an API); where it was convenient to let the database filter results based on permissions subquery. I doubt it's a common pattern, but it's helpful for me... |
Hey @nocko - just to be clear - you know what the unique key |
It could effect the query results, instead of returning the unique key'd item, a failed where clause would return no results. This is the desired behaviour. |
Example: Zone.find(1, where=['owner_id = ANY ((select ARRAY(select org_id from users_orgs where user_id = ?) || ?)::int[])', 1, 1]) generates: SELECT * FROM zones WHERE owner_id = ANY ((select ARRAY(select org_id from users_orgs where user_id = 1) || 1)::int[]) AND id = 1; Explanation: Return zone row with unique id = 1, if the user or one of the user's organizations owns the zone, otherwise return no results. This works well for filtering a collection of rows, but I'd like the same decorator to enforce access control on collections of rows (already working) and specific rows (failed because where clause is overwritten by InteractionBase.select() without falling back to adbapi.ConnectionPool methods. |
if where is None: | ||
where = ["id = ?", id] | ||
else: | ||
where = [" AND ".join([where[0], "id = ?"])] + where[1:] + [id] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line should use the joinWheres
function from utils.py
.
OK - makes sense. I'll merge if you make the one change I suggest in the comments. Thanks for the PR! |
I've never noticed twistar.utils, those are handy. I've implemented at least two of those functions in my own code. Should spend more time reading the code. Thanks. |
Thanks @nocko! I bumped the minor version on pypi as well. Let me know if anything is missing from |
This works as expected when an id is not provided to
DBObject.find(where=...), but failed to work when using specifying an
id DBObject.find(id, where=...). InteractionBase.select() discards the
clause if an id is provided. This patch retains any provided where
clause.