mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-10-08 02:17:08 +02:00
--not-null and --default options to insert/update, closes #24
This commit is contained in:
parent
362359da7e
commit
208f56fbaf
3 changed files with 81 additions and 4 deletions
13
docs/cli.rst
13
docs/cli.rst
|
|
@ -310,6 +310,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_defaults_not_null:
|
||||||
|
|
||||||
|
Setting defaults and not null constraints
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
You can use the ``--not-null`` and ``--default`` options (to both ``insert`` and ``upsert``) to specify columns that should be ``NOT NULL`` or to set database defaults for one or more specific columns::
|
||||||
|
|
||||||
|
$ sqlite-utils insert dogs.db dogs_with_scores dogs-with-scores.json \
|
||||||
|
--not-null=age \
|
||||||
|
--not-null=name \
|
||||||
|
--default age 2 \
|
||||||
|
--default score 5
|
||||||
|
|
||||||
.. _cli_create_index:
|
.. _cli_create_index:
|
||||||
|
|
||||||
Creating indexes
|
Creating indexes
|
||||||
|
|
|
||||||
|
|
@ -299,6 +299,17 @@ def insert_upsert_options(fn):
|
||||||
is_flag=True,
|
is_flag=True,
|
||||||
help="Alter existing table to add any missing columns",
|
help="Alter existing table to add any missing columns",
|
||||||
),
|
),
|
||||||
|
click.option(
|
||||||
|
"--not-null",
|
||||||
|
multiple=True,
|
||||||
|
help="Columns that should be created as NOT NULL",
|
||||||
|
),
|
||||||
|
click.option(
|
||||||
|
"--default",
|
||||||
|
multiple=True,
|
||||||
|
type=(str, str),
|
||||||
|
help="Default value that should be set for a column",
|
||||||
|
),
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
fn = decorator(fn)
|
fn = decorator(fn)
|
||||||
|
|
@ -306,7 +317,18 @@ def insert_upsert_options(fn):
|
||||||
|
|
||||||
|
|
||||||
def insert_upsert_implementation(
|
def insert_upsert_implementation(
|
||||||
path, table, json_file, pk, nl, csv, batch_size, alter, upsert, ignore=False
|
path,
|
||||||
|
table,
|
||||||
|
json_file,
|
||||||
|
pk,
|
||||||
|
nl,
|
||||||
|
csv,
|
||||||
|
batch_size,
|
||||||
|
alter,
|
||||||
|
upsert,
|
||||||
|
ignore=False,
|
||||||
|
not_null=None,
|
||||||
|
default=None,
|
||||||
):
|
):
|
||||||
db = sqlite_utils.Database(path)
|
db = sqlite_utils.Database(path)
|
||||||
if nl and csv:
|
if nl and csv:
|
||||||
|
|
@ -328,6 +350,10 @@ def insert_upsert_implementation(
|
||||||
else:
|
else:
|
||||||
method = db[table].insert_all
|
method = db[table].insert_all
|
||||||
extra_kwargs = {"ignore": ignore}
|
extra_kwargs = {"ignore": ignore}
|
||||||
|
if not_null:
|
||||||
|
extra_kwargs["not_null"] = set(not_null)
|
||||||
|
if default:
|
||||||
|
extra_kwargs["defaults"] = dict(default)
|
||||||
method(docs, pk=pk, batch_size=batch_size, alter=alter, **extra_kwargs)
|
method(docs, pk=pk, batch_size=batch_size, alter=alter, **extra_kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -336,7 +362,9 @@ def insert_upsert_implementation(
|
||||||
@click.option(
|
@click.option(
|
||||||
"--ignore", is_flag=True, default=False, help="Ignore records if pk already exists"
|
"--ignore", is_flag=True, default=False, help="Ignore records if pk already exists"
|
||||||
)
|
)
|
||||||
def insert(path, table, json_file, pk, nl, csv, batch_size, alter, ignore):
|
def insert(
|
||||||
|
path, table, json_file, pk, nl, csv, batch_size, alter, ignore, not_null, default
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Insert records from JSON file into a table, creating the table if it
|
Insert records from JSON file into a table, creating the table if it
|
||||||
does not already exist.
|
does not already exist.
|
||||||
|
|
@ -354,19 +382,31 @@ def insert(path, table, json_file, pk, nl, csv, batch_size, alter, ignore):
|
||||||
alter=alter,
|
alter=alter,
|
||||||
upsert=False,
|
upsert=False,
|
||||||
ignore=ignore,
|
ignore=ignore,
|
||||||
|
not_null=not_null,
|
||||||
|
default=default,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@insert_upsert_options
|
@insert_upsert_options
|
||||||
def upsert(path, table, json_file, pk, nl, csv, batch_size, alter):
|
def upsert(path, table, json_file, pk, nl, csv, batch_size, alter, not_null, default):
|
||||||
"""
|
"""
|
||||||
Upsert records based on their primary key. Works like 'insert' but if
|
Upsert records based on their primary key. Works like 'insert' but if
|
||||||
an incoming record has a primary key that matches an existing record
|
an incoming record has a primary key that matches an existing record
|
||||||
the existing record will be replaced.
|
the existing record will be replaced.
|
||||||
"""
|
"""
|
||||||
insert_upsert_implementation(
|
insert_upsert_implementation(
|
||||||
path, table, json_file, pk, nl, csv, batch_size, alter=alter, upsert=True
|
path,
|
||||||
|
table,
|
||||||
|
json_file,
|
||||||
|
pk,
|
||||||
|
nl,
|
||||||
|
csv,
|
||||||
|
batch_size,
|
||||||
|
alter=alter,
|
||||||
|
upsert=True,
|
||||||
|
not_null=not_null,
|
||||||
|
default=default,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -417,6 +417,30 @@ def test_insert_multiple_with_primary_key(db_path, tmpdir):
|
||||||
assert ["id"] == db["dogs"].pks
|
assert ["id"] == db["dogs"].pks
|
||||||
|
|
||||||
|
|
||||||
|
def test_insert_not_null_default(db_path, tmpdir):
|
||||||
|
json_path = str(tmpdir / "dogs.json")
|
||||||
|
dogs = [
|
||||||
|
{"id": i, "name": "Cleo {}".format(i), "age": i + 3, "score": 10}
|
||||||
|
for i in range(1, 21)
|
||||||
|
]
|
||||||
|
open(json_path, "w").write(json.dumps(dogs))
|
||||||
|
result = CliRunner().invoke(
|
||||||
|
cli.cli,
|
||||||
|
["insert", db_path, "dogs", json_path, "--pk", "id"]
|
||||||
|
+ ["--not-null", "name", "--not-null", "age"]
|
||||||
|
+ ["--default", "score", "5", "--default", "age", "1"],
|
||||||
|
)
|
||||||
|
assert 0 == result.exit_code
|
||||||
|
db = Database(db_path)
|
||||||
|
assert (
|
||||||
|
"CREATE TABLE [dogs] (\n"
|
||||||
|
" [id] INTEGER PRIMARY KEY,\n"
|
||||||
|
" [name] TEXT NOT NULL,\n"
|
||||||
|
" [age] INTEGER NOT NULL DEFAULT '1',\n"
|
||||||
|
" [score] INTEGER DEFAULT '5'\n)"
|
||||||
|
) == db["dogs"].schema
|
||||||
|
|
||||||
|
|
||||||
def test_insert_newline_delimited(db_path):
|
def test_insert_newline_delimited(db_path):
|
||||||
result = CliRunner().invoke(
|
result = CliRunner().invoke(
|
||||||
cli.cli,
|
cli.cli,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue