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

Generic queries #1

Open
wants to merge 2 commits into
base: user-models
Choose a base branch
from
Open

Generic queries #1

wants to merge 2 commits into from

Conversation

anand2312
Copy link
Owner

@anand2312 anand2312 commented Feb 1, 2022

Adds support for:

class Country(BaseModel):
    __table_name__: typing.ClassVar[str] = "countries"
    # fields follow

r = client.from_model(Country).select("*").execute()
reveal_type(r.data)  # Type is List[Country]

More examples

from typing import ClassVar, List, Optional
from datetime import datetime

from pydantic import BaseModel
from postgrest_py import SyncPostgrestClient

class City(BaseModel):
    id: Optional[int]
    created_at: Optional[datetime]
    country_id: Optional[int]
    city_name: Optional[str]

    # if this classvar is set on a model, that is used in queries instead of the model name
    __table_name__: ClassVar[str] = "cities"

class Country(BaseModel):
    id: Optional[int]
    created_at: Optional[datetime]
    country_name: Optional[str]
    capital: Optional[str]
    cities: Optional[List[City]]  # allows to use this model for joins between the tables

    __table_name__: ClassVar[str] = "countries"

client = SyncPostgrestClient(...)

r = client.from_("countries").select("*,cities(*)").execute()
reveal_type(r.data)  # Type is List[Dict[str, Any]], as no model was passed

# this will work for joins as well, as we have included the cities field in the Country model
r = client.from_("countries").select("*,cities(*)").execute(model=Country)
reveal_type(r.data)  # Type is List[Country]

r = client.from_model(Country).select("*,cities(*)").execute()
reveal_type(r.data)  # Type is List[Country]

Note that another model can not be passed to .execute if client.from_model is used (this is to make it play well with the type system; if anyone has any alternate implementation ideas please let me know!)
That is,

client.from_model(Country).select("*").execute(model=FooBar)  # error!

Pros

Works with the type system (tested with pyright)
Gets good editor autocompletion (tested on vscode)
preview

Cons

Request builder classes had to be duplicated to make generic versions that would allow this.

Please let me know if you have other ideas for implementing this feature!

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

Successfully merging this pull request may close these issues.

1 participant