simonw / simonw/sqlite-utils

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

Open Beginner friendly
#588 4 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
2.2k
Forks
172
Avg merge
9m
Merged PRs (30d)
1

Description

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:

https://github.com/simonw/sqlite-utils/blob/1260bdc7bfe31c36c272572c6389125f8de6ef71/sqlite_utils/db.py#L1495

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in sqlite_utils/db.py around line 1495, where the existing Table.get() method is defined, and review its current positional lookup behavior. Add support for keyword column lookup matching the issue's unique-name example, preserving NotFoundError behavior, then run the existing database tests and add coverage for a successful lookup and a missing row.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, sqlite
Domain
databases
Issue type
Feature
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.