.get() method plus support for compound primary keys (#40)

* create_table now handles compound primary keys
* CLI now accepts multiple --pk for compound primary keys
* Docs for compound primary keys with CLI and Python library
* New .get() method plus documentation

Closes #36, closes #39
This commit is contained in:
Simon Willison 2019-07-14 21:28:51 -07:00 committed by GitHub
commit c65b67ca46
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 173 additions and 12 deletions

View file

@ -427,6 +427,31 @@ def test_insert_multiple_with_primary_key(db_path, tmpdir):
assert ["id"] == db["dogs"].pks
def test_insert_multiple_with_compound_primary_key(db_path, tmpdir):
json_path = str(tmpdir / "dogs.json")
dogs = [
{"breed": "mixed", "id": i, "name": "Cleo {}".format(i), "age": i + 3}
for i in range(1, 21)
]
open(json_path, "w").write(json.dumps(dogs))
result = CliRunner().invoke(
cli.cli, ["insert", db_path, "dogs", json_path, "--pk", "id", "--pk", "breed"]
)
assert 0 == result.exit_code
db = Database(db_path)
assert dogs == db.execute_returning_dicts("select * from dogs order by breed, id")
assert {"breed", "id"} == set(db["dogs"].pks)
assert (
"CREATE TABLE [dogs] (\n"
" [breed] TEXT,\n"
" [id] INTEGER,\n"
" [name] TEXT,\n"
" [age] INTEGER,\n"
" PRIMARY KEY ([id], [breed])\n"
")"
) == db["dogs"].schema
def test_insert_not_null_default(db_path, tmpdir):
json_path = str(tmpdir / "dogs.json")
dogs = [

View file

@ -55,6 +55,21 @@ def test_create_table(fresh_db):
) == table.schema
def test_create_table_compound_primary_key(fresh_db):
table = fresh_db.create_table(
"test_table", {"id1": str, "id2": str, "value": int}, pk=("id1", "id2")
)
assert (
"CREATE TABLE [test_table] (\n"
" [id1] TEXT,\n"
" [id2] TEXT,\n"
" [value] INTEGER,\n"
" PRIMARY KEY ([id1], [id2])\n"
")"
) == table.schema
assert ["id1", "id2"] == table.pks
def test_create_table_with_bad_defaults(fresh_db):
with pytest.raises(AssertionError):
fresh_db.create_table(
@ -122,6 +137,13 @@ def test_create_table_from_example(fresh_db, example, expected_columns):
]
def test_create_table_from_example_with_compound_primary_keys(fresh_db):
record = {"name": "Zhang", "group": "staff", "employee_id": 2}
table = fresh_db["people"].insert(record, pk=("group", "employee_id"))
assert ["group", "employee_id"] == table.pks
assert record == table.get(("staff", 2))
def test_create_table_column_order(fresh_db):
fresh_db["table"].insert(
collections.OrderedDict(

View file

@ -1,4 +1,34 @@
import pytest
from sqlite_utils.db import NotFoundError
def test_get_rowid(fresh_db):
dogs = fresh_db["dogs"]
cleo = {"name": "Cleo", "age": 4}
row_id = dogs.insert(cleo).last_rowid
assert cleo == dogs.get(row_id)
def test_get_primary_key(fresh_db):
dogs = fresh_db["dogs"]
cleo = {"name": "Cleo", "age": 4, "id": 5}
last_pk = dogs.insert(cleo, pk="id").last_pk
assert 5 == last_pk
assert cleo == dogs.get(5)
@pytest.mark.parametrize(
"argument,expected_msg",
[(100, None), (None, None), ((1, 2), "Need 1 primary key value"), ("2", None)],
)
def test_get_not_found(argument, expected_msg, fresh_db):
fresh_db["dogs"].insert(
{"id": 1, "name": "Cleo", "age": 4, "is_good": True}, pk="id"
)
with pytest.raises(NotFoundError) as excinfo:
fresh_db["dogs"].get(argument)
if expected_msg is not None:
assert expected_msg == excinfo.value.args[0]
@pytest.mark.parametrize(