mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-09-21 16:04:10 +02:00
create_table now handles compound primary keys, closes #36
This commit is contained in:
parent
90edd0d817
commit
d5dc92876e
2 changed files with 45 additions and 12 deletions
|
|
@ -78,6 +78,7 @@ class NoObviousTable(Exception):
|
||||||
class BadPrimaryKey(Exception):
|
class BadPrimaryKey(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class NotFoundError(Exception):
|
class NotFoundError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
@ -208,11 +209,15 @@ class Database:
|
||||||
raise AlterError(
|
raise AlterError(
|
||||||
"No such column: {}.{}".format(fk.other_table, fk.other_column)
|
"No such column: {}.{}".format(fk.other_table, fk.other_column)
|
||||||
)
|
)
|
||||||
extra = ""
|
|
||||||
column_defs = []
|
column_defs = []
|
||||||
|
# ensure pk is a tuple
|
||||||
|
single_pk = None
|
||||||
|
if isinstance(pk, str):
|
||||||
|
single_pk = pk
|
||||||
for column_name, column_type in column_items:
|
for column_name, column_type in column_items:
|
||||||
column_extras = []
|
column_extras = []
|
||||||
if pk == column_name:
|
if column_name == single_pk:
|
||||||
column_extras.append("PRIMARY KEY")
|
column_extras.append("PRIMARY KEY")
|
||||||
if column_name in not_null:
|
if column_name in not_null:
|
||||||
column_extras.append("NOT NULL")
|
column_extras.append("NOT NULL")
|
||||||
|
|
@ -236,12 +241,17 @@ class Database:
|
||||||
else "",
|
else "",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
extra_pk = ""
|
||||||
|
if single_pk is None and pk and len(pk) > 1:
|
||||||
|
extra_pk = ",\n PRIMARY KEY ({pks})".format(
|
||||||
|
pks=", ".join(["[{}]".format(p) for p in pk])
|
||||||
|
)
|
||||||
columns_sql = ",\n".join(column_defs)
|
columns_sql = ",\n".join(column_defs)
|
||||||
sql = """CREATE TABLE [{table}] (
|
sql = """CREATE TABLE [{table}] (
|
||||||
{columns_sql}
|
{columns_sql}{extra_pk}
|
||||||
){extra};
|
);
|
||||||
""".format(
|
""".format(
|
||||||
table=name, columns_sql=columns_sql, extra=extra
|
table=name, columns_sql=columns_sql, extra_pk=extra_pk
|
||||||
)
|
)
|
||||||
self.conn.execute(sql)
|
self.conn.execute(sql)
|
||||||
return self[name]
|
return self[name]
|
||||||
|
|
@ -401,7 +411,7 @@ class Table:
|
||||||
pk_names = pks
|
pk_names = pks
|
||||||
last_pk = pk_values
|
last_pk = pk_values
|
||||||
wheres = ["[{}] = ?".format(pk_name) for pk_name in pk_names]
|
wheres = ["[{}] = ?".format(pk_name) for pk_name in pk_names]
|
||||||
rows = self.rows_where(' and '.join(wheres), pk_values)
|
rows = self.rows_where(" and ".join(wheres), pk_values)
|
||||||
try:
|
try:
|
||||||
row = list(rows)[0]
|
row = list(rows)[0]
|
||||||
self.last_pk = last_pk
|
self.last_pk = last_pk
|
||||||
|
|
@ -813,12 +823,13 @@ class Table:
|
||||||
self.last_pk = None
|
self.last_pk = None
|
||||||
# self.last_rowid will be 0 if a "INSERT OR IGNORE" happened
|
# self.last_rowid will be 0 if a "INSERT OR IGNORE" happened
|
||||||
if (hash_id or pk) and self.last_rowid:
|
if (hash_id or pk) and self.last_rowid:
|
||||||
self.last_pk = self.db.conn.execute(
|
row = list(self.rows_where("rowid = ?", [self.last_rowid]))[0]
|
||||||
"select [{}] from [{}] where rowid = ?".format(
|
if hash_id:
|
||||||
hash_id or pk, self.name
|
self.last_pk = row[hash_id]
|
||||||
),
|
elif isinstance(pk, str):
|
||||||
(self.last_rowid,),
|
self.last_pk = row[pk]
|
||||||
).fetchone()[0]
|
else:
|
||||||
|
self.last_pk = tuple(row[p] for p in pk)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def upsert(
|
def upsert(
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,21 @@ def test_create_table(fresh_db):
|
||||||
) == table.schema
|
) == 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):
|
def test_create_table_with_bad_defaults(fresh_db):
|
||||||
with pytest.raises(AssertionError):
|
with pytest.raises(AssertionError):
|
||||||
fresh_db.create_table(
|
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):
|
def test_create_table_column_order(fresh_db):
|
||||||
fresh_db["table"].insert(
|
fresh_db["table"].insert(
|
||||||
collections.OrderedDict(
|
collections.OrderedDict(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue