mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-09-28 04:44:26 +02:00
parent
d302835d57
commit
7a52214624
8 changed files with 137 additions and 1 deletions
|
|
@ -12,6 +12,7 @@ Unreleased
|
||||||
- ``sqlite-utils query`` can now read the SQL query from standard input by passing ``-`` in place of the query, for example ``echo "select * from dogs" | sqlite-utils query dogs.db -``. (:issue:`765`)
|
- ``sqlite-utils query`` can now read the SQL query from standard input by passing ``-`` in place of the query, for example ``echo "select * from dogs" | sqlite-utils query dogs.db -``. (:issue:`765`)
|
||||||
- ``sqlite-utils insert`` and ``sqlite-utils upsert`` now accept a ``--code`` option for :ref:`providing a block of Python code <cli_insert_code>` (or a path to a ``.py`` file) that defines a ``rows()`` function or ``rows`` iterable of rows to insert, as an alternative to importing from a file. (:issue:`684`)
|
- ``sqlite-utils insert`` and ``sqlite-utils upsert`` now accept a ``--code`` option for :ref:`providing a block of Python code <cli_insert_code>` (or a path to a ``.py`` file) that defines a ``rows()`` function or ``rows`` iterable of rows to insert, as an alternative to importing from a file. (:issue:`684`)
|
||||||
- ``sqlite-utils insert`` and ``sqlite-utils upsert`` now accept ``--type column-name type`` to :ref:`override the type automatically chosen when the table is created <cli_insert_csv_tsv_column_types>`. This is useful for CSV or TSV columns such as ZIP codes that look like integers but should be stored as ``TEXT`` to preserve leading zeros. (:issue:`131`)
|
- ``sqlite-utils insert`` and ``sqlite-utils upsert`` now accept ``--type column-name type`` to :ref:`override the type automatically chosen when the table is created <cli_insert_csv_tsv_column_types>`. This is useful for CSV or TSV columns such as ZIP codes that look like integers but should be stored as ``TEXT`` to preserve leading zeros. (:issue:`131`)
|
||||||
|
- New ``table.drop_index(name)`` method and ``sqlite-utils drop-index`` command for dropping an index by name. Both accept ``ignore=True``/``--ignore`` to ignore a missing index. (:issue:`626`)
|
||||||
|
|
||||||
.. _v4_0:
|
.. _v4_0:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ This page lists the ``--help`` for every ``sqlite-utils`` CLI sub-command.
|
||||||
go_first = [
|
go_first = [
|
||||||
"query", "memory", "insert", "upsert", "bulk", "search", "transform", "extract",
|
"query", "memory", "insert", "upsert", "bulk", "search", "transform", "extract",
|
||||||
"schema", "insert-files", "analyze-tables", "convert", "tables", "views", "rows",
|
"schema", "insert-files", "analyze-tables", "convert", "tables", "views", "rows",
|
||||||
"triggers", "indexes", "create-database", "create-table", "create-index",
|
"triggers", "indexes", "create-database", "create-table", "create-index", "drop-index",
|
||||||
"migrate", "enable-fts", "populate-fts", "rebuild-fts", "disable-fts"
|
"migrate", "enable-fts", "populate-fts", "rebuild-fts", "disable-fts"
|
||||||
]
|
]
|
||||||
refs = {
|
refs = {
|
||||||
|
|
@ -46,6 +46,7 @@ This page lists the ``--help`` for every ``sqlite-utils`` CLI sub-command.
|
||||||
"add-foreign-keys": "cli_add_foreign_keys",
|
"add-foreign-keys": "cli_add_foreign_keys",
|
||||||
"index-foreign-keys": "cli_index_foreign_keys",
|
"index-foreign-keys": "cli_index_foreign_keys",
|
||||||
"create-index": "cli_create_index",
|
"create-index": "cli_create_index",
|
||||||
|
"drop-index": "cli_drop_index",
|
||||||
"enable-wal": "cli_wal",
|
"enable-wal": "cli_wal",
|
||||||
"enable-counts": "cli_enable_counts",
|
"enable-counts": "cli_enable_counts",
|
||||||
"bulk": "cli_bulk",
|
"bulk": "cli_bulk",
|
||||||
|
|
@ -1006,6 +1007,29 @@ See :ref:`cli_create_index`.
|
||||||
-h, --help Show this message and exit.
|
-h, --help Show this message and exit.
|
||||||
|
|
||||||
|
|
||||||
|
.. _cli_ref_drop_index:
|
||||||
|
|
||||||
|
drop-index
|
||||||
|
==========
|
||||||
|
|
||||||
|
See :ref:`cli_drop_index`.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
Usage: sqlite-utils drop-index [OPTIONS] PATH TABLE INDEX
|
||||||
|
|
||||||
|
Drop an index by index name from the specified table
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
sqlite-utils drop-index chickens.db chickens idx_chickens_name
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--ignore Ignore if index does not exist
|
||||||
|
--load-extension TEXT Path to SQLite extension, with optional :entrypoint
|
||||||
|
-h, --help Show this message and exit.
|
||||||
|
|
||||||
|
|
||||||
.. _cli_ref_migrate:
|
.. _cli_ref_migrate:
|
||||||
|
|
||||||
migrate
|
migrate
|
||||||
|
|
|
||||||
13
docs/cli.rst
13
docs/cli.rst
|
|
@ -2615,6 +2615,19 @@ If your column names are already prefixed with a hyphen you'll need to manually
|
||||||
|
|
||||||
Add the ``--analyze`` option to run ``ANALYZE`` against the index after it has been created.
|
Add the ``--analyze`` option to run ``ANALYZE`` against the index after it has been created.
|
||||||
|
|
||||||
|
.. _cli_drop_index:
|
||||||
|
|
||||||
|
Dropping indexes
|
||||||
|
================
|
||||||
|
|
||||||
|
You can drop an index from an existing table using the ``drop-index`` command:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
sqlite-utils drop-index mydb.db mytable idx_mytable_col1
|
||||||
|
|
||||||
|
Use ``--ignore`` to ignore the error if the index does not exist on that table.
|
||||||
|
|
||||||
.. _cli_fts:
|
.. _cli_fts:
|
||||||
|
|
||||||
Configuring full-text search
|
Configuring full-text search
|
||||||
|
|
|
||||||
|
|
@ -2877,6 +2877,14 @@ Use ``if_not_exists=True`` to do nothing if an index with that name already exis
|
||||||
|
|
||||||
Pass ``analyze=True`` to run ``ANALYZE`` against the new index after creating it.
|
Pass ``analyze=True`` to run ``ANALYZE`` against the new index after creating it.
|
||||||
|
|
||||||
|
You can drop an index from a table using ``.drop_index(index_name)``:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
db.table("dogs").drop_index("idx_dogs_name")
|
||||||
|
|
||||||
|
Use ``ignore=True`` to ignore the error if the index does not exist.
|
||||||
|
|
||||||
.. _python_api_analyze:
|
.. _python_api_analyze:
|
||||||
|
|
||||||
Optimizing index usage with ANALYZE
|
Optimizing index usage with ANALYZE
|
||||||
|
|
|
||||||
|
|
@ -692,6 +692,34 @@ def create_index(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command(name="drop-index")
|
||||||
|
@click.argument(
|
||||||
|
"path",
|
||||||
|
type=click.Path(exists=True, file_okay=True, dir_okay=False, allow_dash=False),
|
||||||
|
required=True,
|
||||||
|
)
|
||||||
|
@click.argument("table")
|
||||||
|
@click.argument("index")
|
||||||
|
@click.option("--ignore", help="Ignore if index does not exist", is_flag=True)
|
||||||
|
@load_extension_option
|
||||||
|
def drop_index(path, table, index, ignore, load_extension):
|
||||||
|
"""
|
||||||
|
Drop an index by index name from the specified table
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
\b
|
||||||
|
sqlite-utils drop-index chickens.db chickens idx_chickens_name
|
||||||
|
"""
|
||||||
|
db = sqlite_utils.Database(path)
|
||||||
|
_register_db_for_cleanup(db)
|
||||||
|
_load_extensions(db, load_extension)
|
||||||
|
try:
|
||||||
|
db.table(table).drop_index(index, ignore=ignore)
|
||||||
|
except OperationalError as ex:
|
||||||
|
raise click.ClickException(str(ex))
|
||||||
|
|
||||||
|
|
||||||
@cli.command(name="enable-fts")
|
@cli.command(name="enable-fts")
|
||||||
@click.argument(
|
@click.argument(
|
||||||
"path",
|
"path",
|
||||||
|
|
|
||||||
|
|
@ -3080,6 +3080,22 @@ class Table(Queryable):
|
||||||
self.db.analyze(created_index_name)
|
self.db.analyze(created_index_name)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def drop_index(self, index_name: str, ignore: bool = False):
|
||||||
|
"""
|
||||||
|
Drop an index on this table.
|
||||||
|
|
||||||
|
:param index_name: Name of the index to drop
|
||||||
|
:param ignore: Set to ``True`` to ignore the error if the index does not exist
|
||||||
|
"""
|
||||||
|
if index_name not in {index.name for index in self.indexes}:
|
||||||
|
if ignore:
|
||||||
|
return self
|
||||||
|
raise OperationalError(
|
||||||
|
"No index named {} on table {}".format(index_name, self.name)
|
||||||
|
)
|
||||||
|
self.db.execute("DROP INDEX {}".format(quote_identifier(index_name)))
|
||||||
|
return self
|
||||||
|
|
||||||
def add_column(
|
def add_column(
|
||||||
self,
|
self,
|
||||||
col_name: str,
|
col_name: str,
|
||||||
|
|
|
||||||
|
|
@ -291,6 +291,24 @@ def test_create_index(db_path):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_drop_index(db_path):
|
||||||
|
db = Database(db_path)
|
||||||
|
db["Gosh"].create_index(["c1"])
|
||||||
|
assert [index.name for index in db["Gosh"].indexes] == ["idx_Gosh_c1"]
|
||||||
|
result = CliRunner().invoke(cli.cli, ["drop-index", db_path, "Gosh", "idx_Gosh_c1"])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert db["Gosh"].indexes == []
|
||||||
|
|
||||||
|
result = CliRunner().invoke(cli.cli, ["drop-index", db_path, "Gosh", "idx_Gosh_c1"])
|
||||||
|
assert result.exit_code == 1
|
||||||
|
assert "No index named idx_Gosh_c1" in result.output
|
||||||
|
|
||||||
|
result = CliRunner().invoke(
|
||||||
|
cli.cli, ["drop-index", db_path, "Gosh", "idx_Gosh_c1", "--ignore"]
|
||||||
|
)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
|
||||||
def test_create_index_analyze(db_path):
|
def test_create_index_analyze(db_path):
|
||||||
db = Database(db_path)
|
db = Database(db_path)
|
||||||
assert "sqlite_stat1" not in db.table_names()
|
assert "sqlite_stat1" not in db.table_names()
|
||||||
|
|
|
||||||
|
|
@ -809,6 +809,34 @@ def test_create_index_if_not_exists(fresh_db):
|
||||||
dogs.create_index(["name"], if_not_exists=True)
|
dogs.create_index(["name"], if_not_exists=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_drop_index(fresh_db):
|
||||||
|
dogs = fresh_db["dogs"]
|
||||||
|
dogs.insert({"name": "Cleo", "twitter": "cleopaws", "age": 3, "is_good_dog": True})
|
||||||
|
dogs.create_index(["name"])
|
||||||
|
assert [index.name for index in dogs.indexes] == ["idx_dogs_name"]
|
||||||
|
dogs.drop_index("idx_dogs_name")
|
||||||
|
assert dogs.indexes == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_drop_index_ignore(fresh_db):
|
||||||
|
dogs = fresh_db["dogs"]
|
||||||
|
dogs.insert({"name": "Cleo"})
|
||||||
|
with pytest.raises(OperationalError, match="No index named idx_dogs_name"):
|
||||||
|
dogs.drop_index("idx_dogs_name")
|
||||||
|
dogs.drop_index("idx_dogs_name", ignore=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_drop_index_wrong_table(fresh_db):
|
||||||
|
dogs = fresh_db["dogs"]
|
||||||
|
cats = fresh_db["cats"]
|
||||||
|
dogs.insert({"name": "Cleo"})
|
||||||
|
cats.insert({"name": "Misty"})
|
||||||
|
dogs.create_index(["name"])
|
||||||
|
with pytest.raises(OperationalError, match="No index named idx_dogs_name"):
|
||||||
|
cats.drop_index("idx_dogs_name")
|
||||||
|
assert [index.name for index in dogs.indexes] == ["idx_dogs_name"]
|
||||||
|
|
||||||
|
|
||||||
def test_create_index_desc(fresh_db):
|
def test_create_index_desc(fresh_db):
|
||||||
dogs = fresh_db["dogs"]
|
dogs = fresh_db["dogs"]
|
||||||
dogs.insert({"name": "Cleo", "twitter": "cleopaws", "age": 3, "is good dog": True})
|
dogs.insert({"name": "Cleo", "twitter": "cleopaws", "age": 3, "is good dog": True})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue