mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-09-28 12:54:15 +02:00
create-table --not-null, --default, --fk, refs #27
This commit is contained in:
parent
99a7906fd9
commit
4d5916075d
3 changed files with 147 additions and 16 deletions
51
docs/cli.rst
51
docs/cli.rst
|
|
@ -348,6 +348,57 @@ This will create a table called ``mytable`` with two columns - an integer ``id``
|
||||||
|
|
||||||
You can pass as many column-name column-type pairs as you like. Valid types are ``integer``, ``text``, ``float`` and ``blob``.
|
You can pass as many column-name column-type pairs as you like. Valid types are ``integer``, ``text``, ``float`` and ``blob``.
|
||||||
|
|
||||||
|
You can specify columns that should be NOT NULL using ``--not-null colname``. You can specify default values for columns using ``--default colname defaultvalue``.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
$ sqlite-utils create-table mydb.db mytable \
|
||||||
|
id integer \
|
||||||
|
name text \
|
||||||
|
age integer \
|
||||||
|
is_good integer \
|
||||||
|
--not-null name \
|
||||||
|
--not-null age \
|
||||||
|
--default is_good 1 \
|
||||||
|
--pk=id
|
||||||
|
|
||||||
|
$ sqlite-utils tables mydb.db --schema -t
|
||||||
|
table schema
|
||||||
|
------- --------------------------------
|
||||||
|
mytable CREATE TABLE [mytable] (
|
||||||
|
[id] INTEGER PRIMARY KEY,
|
||||||
|
[name] TEXT NOT NULL,
|
||||||
|
[age] INTEGER NOT NULL,
|
||||||
|
[is_good] INTEGER DEFAULT '1'
|
||||||
|
)
|
||||||
|
|
||||||
|
You can specify foreign key relationships between the tables you are creating using ``--fk colname othertable othercolumn``::
|
||||||
|
|
||||||
|
$ sqlite-utils create-table books.db authors \
|
||||||
|
id integer \
|
||||||
|
name text \
|
||||||
|
--pk=id
|
||||||
|
|
||||||
|
$ sqlite-utils create-table books.db books \
|
||||||
|
id integer \
|
||||||
|
title text \
|
||||||
|
author_id integer \
|
||||||
|
--pk=id \
|
||||||
|
--fk author_id authors id
|
||||||
|
|
||||||
|
$ sqlite-utils tables books.db --schema -t
|
||||||
|
table schema
|
||||||
|
------- -------------------------------------------------
|
||||||
|
authors CREATE TABLE [authors] (
|
||||||
|
[id] INTEGER PRIMARY KEY,
|
||||||
|
[name] TEXT
|
||||||
|
)
|
||||||
|
books CREATE TABLE [books] (
|
||||||
|
[id] INTEGER PRIMARY KEY,
|
||||||
|
[title] TEXT,
|
||||||
|
[author_id] INTEGER REFERENCES [authors]([id])
|
||||||
|
)
|
||||||
|
|
||||||
.. _cli_add_column:
|
.. _cli_add_column:
|
||||||
|
|
||||||
Adding columns
|
Adding columns
|
||||||
|
|
|
||||||
|
|
@ -539,7 +539,22 @@ def upsert(
|
||||||
@click.argument("table")
|
@click.argument("table")
|
||||||
@click.argument("columns", nargs=-1, required=True)
|
@click.argument("columns", nargs=-1, required=True)
|
||||||
@click.option("--pk", help="Column to use as primary key")
|
@click.option("--pk", help="Column to use as primary key")
|
||||||
def create_table(path, table, columns, pk):
|
@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",
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
"--fk",
|
||||||
|
multiple=True,
|
||||||
|
type=(str, str, str),
|
||||||
|
help="Column, other table, other column to set as a foreign key",
|
||||||
|
)
|
||||||
|
def create_table(path, table, columns, pk, not_null, default, fk):
|
||||||
"Add an index to the specified table covering the specified columns"
|
"Add an index to the specified table covering the specified columns"
|
||||||
db = sqlite_utils.Database(path)
|
db = sqlite_utils.Database(path)
|
||||||
if len(columns) % 2 == 1:
|
if len(columns) % 2 == 1:
|
||||||
|
|
@ -556,7 +571,9 @@ def create_table(path, table, columns, pk):
|
||||||
"column types must be one of {}".format(VALID_COLUMN_TYPES)
|
"column types must be one of {}".format(VALID_COLUMN_TYPES)
|
||||||
)
|
)
|
||||||
coltypes[name] = ctype.upper()
|
coltypes[name] = ctype.upper()
|
||||||
db[table].create(coltypes, pk=pk)
|
db[table].create(
|
||||||
|
coltypes, pk=pk, not_null=not_null, defaults=dict(default), foreign_keys=fk
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
|
|
|
||||||
|
|
@ -863,15 +863,17 @@ def test_upsert_alter(db_path, tmpdir):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_create_table():
|
@pytest.mark.parametrize(
|
||||||
runner = CliRunner()
|
"args,schema",
|
||||||
with runner.isolated_filesystem():
|
[
|
||||||
result = runner.invoke(
|
# No primary key
|
||||||
cli.cli,
|
(
|
||||||
|
["name", "text", "age", "integer",],
|
||||||
|
("CREATE TABLE [t] (\n [name] TEXT,\n [age] INTEGER\n)"),
|
||||||
|
),
|
||||||
|
# All types:
|
||||||
|
(
|
||||||
[
|
[
|
||||||
"create-table",
|
|
||||||
"test.db",
|
|
||||||
"t",
|
|
||||||
"id",
|
"id",
|
||||||
"integer",
|
"integer",
|
||||||
"name",
|
"name",
|
||||||
|
|
@ -885,15 +887,76 @@ def test_create_table():
|
||||||
"--pk",
|
"--pk",
|
||||||
"id",
|
"id",
|
||||||
],
|
],
|
||||||
|
(
|
||||||
|
"CREATE TABLE [t] (\n"
|
||||||
|
" [id] INTEGER PRIMARY KEY,\n"
|
||||||
|
" [name] TEXT,\n"
|
||||||
|
" [age] INTEGER,\n"
|
||||||
|
" [weight] FLOAT,\n"
|
||||||
|
" [thumbnail] BLOB\n"
|
||||||
|
")"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
# Not null:
|
||||||
|
(
|
||||||
|
["name", "text", "--not-null", "name"],
|
||||||
|
("CREATE TABLE [t] (\n" " [name] TEXT NOT NULL\n" ")"),
|
||||||
|
),
|
||||||
|
# Default:
|
||||||
|
(
|
||||||
|
["age", "integer", "--default", "age", "3"],
|
||||||
|
("CREATE TABLE [t] (\n" " [age] INTEGER DEFAULT '3'\n" ")"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_create_table(args, schema):
|
||||||
|
runner = CliRunner()
|
||||||
|
with runner.isolated_filesystem():
|
||||||
|
result = runner.invoke(
|
||||||
|
cli.cli, ["create-table", "test.db", "t",] + args, catch_exceptions=False
|
||||||
)
|
)
|
||||||
assert 0 == result.exit_code
|
assert 0 == result.exit_code
|
||||||
db = Database("test.db")
|
db = Database("test.db")
|
||||||
|
assert schema == db["t"].schema
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_table_foreign_key():
|
||||||
|
runner = CliRunner()
|
||||||
|
creates = (
|
||||||
|
["authors", "id", "integer", "name", "text", "--pk", "id"],
|
||||||
|
[
|
||||||
|
"books",
|
||||||
|
"id",
|
||||||
|
"integer",
|
||||||
|
"title",
|
||||||
|
"text",
|
||||||
|
"author_id",
|
||||||
|
"integer",
|
||||||
|
"--pk",
|
||||||
|
"id",
|
||||||
|
"--fk",
|
||||||
|
"author_id",
|
||||||
|
"authors",
|
||||||
|
"id",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
with runner.isolated_filesystem():
|
||||||
|
for args in creates:
|
||||||
|
result = runner.invoke(
|
||||||
|
cli.cli, ["create-table", "books.db"] + args, catch_exceptions=False
|
||||||
|
)
|
||||||
|
assert 0 == result.exit_code
|
||||||
|
db = Database("books.db")
|
||||||
assert (
|
assert (
|
||||||
"CREATE TABLE [t] (\n"
|
"CREATE TABLE [authors] (\n"
|
||||||
" [id] INTEGER PRIMARY KEY,\n"
|
" [id] INTEGER PRIMARY KEY,\n"
|
||||||
" [name] TEXT,\n"
|
" [name] TEXT\n"
|
||||||
" [age] INTEGER,\n"
|
|
||||||
" [weight] FLOAT,\n"
|
|
||||||
" [thumbnail] BLOB\n"
|
|
||||||
")"
|
")"
|
||||||
) == db["t"].schema
|
) == db["authors"].schema
|
||||||
|
assert (
|
||||||
|
"CREATE TABLE [books] (\n"
|
||||||
|
" [id] INTEGER PRIMARY KEY,\n"
|
||||||
|
" [title] TEXT,\n"
|
||||||
|
" [author_id] INTEGER REFERENCES [authors]([id])\n"
|
||||||
|
")"
|
||||||
|
) == db["books"].schema
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue