mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-09-28 04:44:26 +02:00
sqlite-utils add-foreign-keys command, closes #157
This commit is contained in:
parent
7805d53bcf
commit
3cc1944e53
3 changed files with 81 additions and 0 deletions
13
docs/cli.rst
13
docs/cli.rst
|
|
@ -621,6 +621,19 @@ If you omit the other table and other column references ``sqlite-utils`` will at
|
||||||
|
|
||||||
See :ref:`python_api_add_foreign_key` in the Python API documentation for further details, including how the automatic table guessing mechanism works.
|
See :ref:`python_api_add_foreign_key` in the Python API documentation for further details, including how the automatic table guessing mechanism works.
|
||||||
|
|
||||||
|
.. _cli_add_foreign_keys:
|
||||||
|
|
||||||
|
Adding multiple foreign keys at once
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
Adding a foreign key requires a ``VACUUM``. On large databases this can be an expensive operation, so if you are adding multiple foreign keys you can combine them into one operation (and hence one ``VACUUM``) using ``add-foreign-keys``::
|
||||||
|
|
||||||
|
$ sqlite-utils add-foreign-keys books.db \
|
||||||
|
books author_id authors id \
|
||||||
|
authors country_id countries id
|
||||||
|
|
||||||
|
When you are using this command each foreign key needs to be defined in full, as four arguments - the table, column, other table and other column.
|
||||||
|
|
||||||
.. _cli_index_foreign_keys:
|
.. _cli_index_foreign_keys:
|
||||||
|
|
||||||
Adding indexes for all foreign keys
|
Adding indexes for all foreign keys
|
||||||
|
|
|
||||||
|
|
@ -323,6 +323,36 @@ def add_foreign_key(path, table, column, other_table, other_column):
|
||||||
raise click.ClickException(e)
|
raise click.ClickException(e)
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command(name="add-foreign-keys")
|
||||||
|
@click.argument(
|
||||||
|
"path",
|
||||||
|
type=click.Path(exists=True, file_okay=True, dir_okay=False, allow_dash=False),
|
||||||
|
required=True,
|
||||||
|
)
|
||||||
|
@click.argument("foreign_key", nargs=-1)
|
||||||
|
def add_foreign_keys(path, foreign_key):
|
||||||
|
"""
|
||||||
|
Add multiple new foreign key constraints to a database. Example usage:
|
||||||
|
|
||||||
|
\b
|
||||||
|
sqlite-utils add-foreign-keys my.db \\
|
||||||
|
books author_id authors id \\
|
||||||
|
authors country_id countries id
|
||||||
|
"""
|
||||||
|
db = sqlite_utils.Database(path)
|
||||||
|
if len(foreign_key) % 4 != 0:
|
||||||
|
raise click.ClickException(
|
||||||
|
"Each foreign key requires four values: table, column, other_table, other_column"
|
||||||
|
)
|
||||||
|
tuples = []
|
||||||
|
for i in range(len(foreign_key) // 4):
|
||||||
|
tuples.append(tuple(foreign_key[i * 4 : (i * 4) + 4]))
|
||||||
|
try:
|
||||||
|
db.add_foreign_keys(tuples)
|
||||||
|
except AlterError as e:
|
||||||
|
raise click.ClickException(e)
|
||||||
|
|
||||||
|
|
||||||
@cli.command(name="index-foreign-keys")
|
@cli.command(name="index-foreign-keys")
|
||||||
@click.argument(
|
@click.argument(
|
||||||
"path",
|
"path",
|
||||||
|
|
|
||||||
|
|
@ -1405,3 +1405,41 @@ def test_query_update(db_path, args, expected):
|
||||||
assert db.execute_returning_dicts("select * from dogs") == [
|
assert db.execute_returning_dicts("select * from dogs") == [
|
||||||
{"id": 1, "age": 5, "name": "Cleo"},
|
{"id": 1, "age": 5, "name": "Cleo"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_foreign_keys(db_path):
|
||||||
|
db = Database(db_path)
|
||||||
|
db["countries"].insert({"id": 7, "name": "Panama"}, pk="id")
|
||||||
|
db["authors"].insert({"id": 3, "name": "Matilda", "country_id": 7}, pk="id")
|
||||||
|
db["books"].insert({"id": 2, "title": "Wolf anatomy", "author_id": 3}, pk="id")
|
||||||
|
assert db["authors"].foreign_keys == []
|
||||||
|
assert db["books"].foreign_keys == []
|
||||||
|
result = CliRunner().invoke(
|
||||||
|
cli.cli,
|
||||||
|
[
|
||||||
|
"add-foreign-keys",
|
||||||
|
db_path,
|
||||||
|
"authors",
|
||||||
|
"country_id",
|
||||||
|
"countries",
|
||||||
|
"id",
|
||||||
|
"books",
|
||||||
|
"author_id",
|
||||||
|
"authors",
|
||||||
|
"id",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert db["authors"].foreign_keys == [
|
||||||
|
ForeignKey(
|
||||||
|
table="authors",
|
||||||
|
column="country_id",
|
||||||
|
other_table="countries",
|
||||||
|
other_column="id",
|
||||||
|
)
|
||||||
|
]
|
||||||
|
assert db["books"].foreign_keys == [
|
||||||
|
ForeignKey(
|
||||||
|
table="books", column="author_id", other_table="authors", other_column="id"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue