Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend the base SQLAlchemy utility methods in models/utils.py to allow loading relationships in asyncpg #41

Closed
devraj opened this issue Sep 8, 2022 · 0 comments
Assignees

Comments

@devraj
Copy link
Member

devraj commented Sep 8, 2022

Due to how the 2.0 syntax works and using asyncpg writing generic helper methods when using relationships becomes a lot trickers. Essentially you have to write a select as follows:

        query = select(cls).options(selectinload(cls.memberships),\
            selectinload(cls.card_holder))

for the relationships to work. This makes writing generic CRUD wrapper difficult.

The proposal here is to write a generic method called _get_select which provides the joined configuration of the select statement which other get methods can use to apply conditions to e.g:

        query = select(cls).options(selectinload(cls.memberships),\
            selectinload(cls.card_holder))\
            .where(or_(cls.email == email,\
                cls.mobile_number == mobile_number))

a refactored version would then look like

        query = cls._get_select()
            .where(or_(cls.email == email,\
                cls.mobile_number == mobile_number))

each class inheriting from the ModelCRUDMixin can override that to provide the appropriate configuration, allowing the global getting to work across models and making it easier to write other getters.

Another benefit of this approach will be that as the relationships are modified they can be changed in one spot and all other getters remain unchanged.

See also #38

@devraj devraj self-assigned this Sep 8, 2022
devraj added a commit that referenced this issue Oct 14, 2022
asyncpg does not support joinload and requires queries to use the selectinload option
to construct queries which loads the relationship data.

it's likely that each model will have more than one getter, this pattern (documented)
allows you to construct the base query (which can be overridden) and then each
getter uses this inturn allowing you to maintain the selectinload code in one spot.
@devraj devraj closed this as completed Oct 14, 2022
devraj added a commit that referenced this issue Mar 6, 2023
the  method in the  package simply refreshed the model
post create and returned it to the calling function, while this will load the
identifier but it won't load any dynamically configured relationships

we previous fixed this by introducing a _base_get_query in issue #41
the create method now calls the  method to get a fully populated
model
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant