mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-07-23 01:14:31 +02:00
ignore=True argument for add_foreign_key, closes #112
Also --ignore for add-foreign-key command Plus table.add_foreign_key(...) now returns self, allowing more chaining
This commit is contained in:
parent
ecb50c8f76
commit
e23eedb4ce
6 changed files with 48 additions and 9 deletions
|
|
@ -619,6 +619,10 @@ If you omit the other table and other column references ``sqlite-utils`` will at
|
|||
|
||||
$ sqlite-utils add-foreign-key books.db books author_id
|
||||
|
||||
Add ``--ignore`` to ignore an existing foreign key (as opposed to returning an error)::
|
||||
|
||||
$ sqlite-utils add-foreign-key books.db books author_id --ignore
|
||||
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -858,6 +858,12 @@ The ``table.add_foreign_key(column, other_table, other_column)`` method takes th
|
|||
|
||||
This method first checks that the specified foreign key references tables and columns that exist and does not clash with an existing foreign key. It will raise a ``sqlite_utils.db.AlterError`` exception if these checks fail.
|
||||
|
||||
To ignore the case where the key already exists, use ``ignore=True``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
db["books"].add_foreign_key("author_id", "authors", "id", ignore=True)
|
||||
|
||||
.. _python_api_add_foreign_keys:
|
||||
|
||||
Adding multiple foreign key constraints at once
|
||||
|
|
|
|||
|
|
@ -308,7 +308,12 @@ def add_column(path, table, col_name, col_type, fk, fk_col, not_null_default):
|
|||
@click.argument("column")
|
||||
@click.argument("other_table", required=False)
|
||||
@click.argument("other_column", required=False)
|
||||
def add_foreign_key(path, table, column, other_table, other_column):
|
||||
@click.option(
|
||||
"--ignore",
|
||||
is_flag=True,
|
||||
help="If foreign key already exists, do nothing",
|
||||
)
|
||||
def add_foreign_key(path, table, column, other_table, other_column, ignore):
|
||||
"""
|
||||
Add a new foreign key constraint to an existing table. Example usage:
|
||||
|
||||
|
|
@ -318,7 +323,7 @@ def add_foreign_key(path, table, column, other_table, other_column):
|
|||
"""
|
||||
db = sqlite_utils.Database(path)
|
||||
try:
|
||||
db[table].add_foreign_key(column, other_table, other_column)
|
||||
db[table].add_foreign_key(column, other_table, other_column, ignore=ignore)
|
||||
except AlterError as e:
|
||||
raise click.ClickException(e)
|
||||
|
||||
|
|
|
|||
|
|
@ -781,7 +781,9 @@ class Table(Queryable):
|
|||
else:
|
||||
return pks[0].name
|
||||
|
||||
def add_foreign_key(self, column, other_table=None, other_column=None):
|
||||
def add_foreign_key(
|
||||
self, column, other_table=None, other_column=None, ignore=False
|
||||
):
|
||||
# Ensure column exists
|
||||
if column not in self.columns_dict:
|
||||
raise AlterError("No such column: {}".format(column))
|
||||
|
|
@ -806,12 +808,16 @@ class Table(Queryable):
|
|||
and fk.other_table == other_table
|
||||
and fk.other_column == other_column
|
||||
):
|
||||
raise AlterError(
|
||||
"Foreign key already exists for {} => {}.{}".format(
|
||||
column, other_table, other_column
|
||||
if ignore:
|
||||
return self
|
||||
else:
|
||||
raise AlterError(
|
||||
"Foreign key already exists for {} => {}.{}".format(
|
||||
column, other_table, other_column
|
||||
)
|
||||
)
|
||||
)
|
||||
self.db.add_foreign_keys([(self.name, column, other_table, other_column)])
|
||||
return self
|
||||
|
||||
def enable_fts(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -272,16 +272,24 @@ def test_add_foreign_key(db_path, args, assert_message):
|
|||
table="books", column="author_id", other_table="authors", other_column="id"
|
||||
)
|
||||
] == db["books"].foreign_keys
|
||||
|
||||
# Error if we try to add it twice:
|
||||
result = CliRunner().invoke(
|
||||
cli.cli, ["add-foreign-key", db_path, "books", "author_id", "authors", "id"]
|
||||
)
|
||||
|
||||
assert 0 != result.exit_code
|
||||
assert (
|
||||
"Error: Foreign key already exists for author_id => authors.id"
|
||||
== result.output.strip()
|
||||
)
|
||||
|
||||
# No error if we add it twice with --ignore
|
||||
result = CliRunner().invoke(
|
||||
cli.cli,
|
||||
["add-foreign-key", db_path, "books", "author_id", "authors", "id", "--ignore"],
|
||||
)
|
||||
assert 0 == result.exit_code
|
||||
|
||||
# Error if we try against an invalid column
|
||||
result = CliRunner().invoke(
|
||||
cli.cli, ["add-foreign-key", db_path, "books", "author_id", "authors", "bad"]
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from sqlite_utils.db import (
|
|||
AlterError,
|
||||
NoObviousTable,
|
||||
ForeignKey,
|
||||
Table,
|
||||
)
|
||||
from sqlite_utils.utils import sqlite3
|
||||
import collections
|
||||
|
|
@ -348,7 +349,9 @@ def test_add_foreign_key(fresh_db):
|
|||
]
|
||||
)
|
||||
assert [] == fresh_db["books"].foreign_keys
|
||||
fresh_db["books"].add_foreign_key("author_id", "authors", "id")
|
||||
t = fresh_db["books"].add_foreign_key("author_id", "authors", "id")
|
||||
# Ensure it returned self:
|
||||
assert isinstance(t, Table) and t.name == "books"
|
||||
assert [
|
||||
ForeignKey(
|
||||
table="books", column="author_id", other_table="authors", other_column="id"
|
||||
|
|
@ -379,6 +382,13 @@ def test_add_foreign_key_error_if_already_exists(fresh_db):
|
|||
assert "Foreign key already exists for author_id => authors.id" == ex.value.args[0]
|
||||
|
||||
|
||||
def test_add_foreign_key_no_error_if_exists_and_ignore_true(fresh_db):
|
||||
fresh_db["books"].insert({"title": "Hedgehogs of the world", "author_id": 1})
|
||||
fresh_db["authors"].insert({"id": 1, "name": "Sally"}, pk="id")
|
||||
fresh_db["books"].add_foreign_key("author_id", "authors", "id")
|
||||
fresh_db["books"].add_foreign_key("author_id", "authors", "id", ignore=True)
|
||||
|
||||
|
||||
def test_add_foreign_keys(fresh_db):
|
||||
fresh_db["authors"].insert_all(
|
||||
[{"id": 1, "name": "Sally"}, {"id": 2, "name": "Asheesh"}], pk="id"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue