sqlite-utils create-index command, closes #14

This commit is contained in:
Simon Willison 2019-02-24 11:11:21 -08:00
commit 8a5d0d80c3
3 changed files with 95 additions and 0 deletions

View file

@ -221,6 +221,23 @@ After running the above ``dogs.json`` example, try running this::
This will replace the record for id=2 (Pancakes) with a new record with an updated age.
.. _cli_create_index:
Creating indexes
================
You can add an index to an existing table using the ``create-index`` subcommand::
$ sqlite-utils create-index mydb.db mytable col1 [col2...]
This can be used to create indexes against a single column or multiple columns.
The name of the index will be automatically derived from the table and columns. To specify a different name, use ``--name=name_of_index``.
Use the ``--unique`` option to create a unique index.
Use ``--if-not-exists`` to avoid attempting to create the index if one with that name already exists.
.. _cli_fts:
Configuring full-text search

View file

@ -134,6 +134,30 @@ def optimize(path, no_vacuum):
db.vacuum()
@cli.command(name="create-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("column", nargs=-1, required=True)
@click.option("--name", help="Explicit name for the new index")
@click.option("--unique", help="Make this a unique index", default=False, is_flag=True)
@click.option(
"--if-not-exists",
help="Ignore if index already exists",
default=False,
is_flag=True,
)
def create_index(path, table, column, name, unique, if_not_exists):
"Add an index to the specified table covering the specified columns"
db = sqlite_utils.Database(path)
db[table].create_index(
column, index_name=name, unique=unique, if_not_exists=if_not_exists
)
@cli.command(name="enable-fts")
@click.argument(
"path",

View file

@ -1,4 +1,5 @@
from sqlite_utils import cli, Database
from sqlite_utils.db import Index
from click.testing import CliRunner
import json
import os
@ -116,6 +117,59 @@ def test_output_table(db_path, fmt, expected):
assert expected == result.output.strip()
def test_create_index(db_path):
db = Database(db_path)
assert [] == db["Gosh"].indexes
result = CliRunner().invoke(cli.cli, ["create-index", db_path, "Gosh", "c1"])
assert 0 == result.exit_code
assert [
Index(
seq=0, name="idx_Gosh_c1", unique=0, origin="c", partial=0, columns=["c1"]
)
] == db["Gosh"].indexes
# Try with a custom name
result = CliRunner().invoke(
cli.cli, ["create-index", db_path, "Gosh", "c2", "--name", "blah"]
)
assert 0 == result.exit_code
assert [
Index(seq=0, name="blah", unique=0, origin="c", partial=0, columns=["c2"]),
Index(
seq=1, name="idx_Gosh_c1", unique=0, origin="c", partial=0, columns=["c1"]
),
] == db["Gosh"].indexes
# Try a two-column unique index
create_index_unique_args = [
"create-index",
db_path,
"Gosh2",
"c1",
"c2",
"--unique",
]
result = CliRunner().invoke(cli.cli, create_index_unique_args)
assert 0 == result.exit_code
assert [
Index(
seq=0,
name="idx_Gosh2_c1_c2",
unique=1,
origin="c",
partial=0,
columns=["c1", "c2"],
)
] == db["Gosh2"].indexes
# Trying to create the same index should fail
assert -1 == CliRunner().invoke(cli.cli, create_index_unique_args).exit_code
# ... unless we use --if-not-exists
assert (
0
== CliRunner()
.invoke(cli.cli, create_index_unique_args + ["--if-not-exists"])
.exit_code
)
def test_enable_fts(db_path):
assert None == Database(db_path)["Gosh"].detect_fts()
result = CliRunner().invoke(