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

table.get(column=value) option for retrieving things not by their primary key #588

Open
simonw opened this issue Aug 28, 2023 · 2 comments

Comments

@simonw
Copy link
Owner

simonw commented Aug 28, 2023

This came up working on this feature:

I have a table with this schema:

CREATE TABLE [collections] (
   [id] INTEGER PRIMARY KEY,
   [name] TEXT,
   [model] TEXT
);
CREATE UNIQUE INDEX [idx_collections_name]
    ON [collections] ([name]);

So the primary key is an integer (because it's going to have a huge number of rows foreign key related to it, and I don't want to store a larger text value thousands of times), but there is a unique constraint on the name - that would be the primary key column if not for all of those foreign keys.

Problem is, fetching the collection by name is actually pretty inconvenient.

Fetch by numeric ID:

try:
    table["collections"].get(1)
except NotFoundError:
    # It doesn't exist

Fetching by name:

def get_collection(db, collection):
    rows = db["collections"].rows_where("name = ?", [collection])
    try:
        return next(rows)
    except StopIteration:
        raise NotFoundError("Collection not found: {}".format(collection))

It would be neat if, for columns where we know that we should always get 0 or one result, we could do this instead:

try:
    collection = table["collections"].get(name="entries")
except NotFoundError:
    # It doesn't exist

The existing .get() method doesn't have any non-positional arguments, so using **kwargs like that should work:

def get(self, pk_values: Union[list, tuple, str, int]) -> dict:

@simonw
Copy link
Owner Author

simonw commented Aug 28, 2023

@rsyring
Copy link

rsyring commented Jan 22, 2024

Would be nice to have something like this. I've created a get_by() method previously to do the same thing but adding it to get() makes sense.

Tangentially, a first() method that worked similarly but returned None instead of raising when a record isn't found would also be helpful IMO.

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

2 participants