mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-09-10 18:44:20 +02:00
Also made it so .duplicate() raises new NoTable exception rather than raising an AssertionError if the source table does not exist.
This commit is contained in:
parent
da030d49fd
commit
c710ade644
7 changed files with 80 additions and 3 deletions
|
|
@ -1176,6 +1176,20 @@ reset-counts
|
||||||
-h, --help Show this message and exit.
|
-h, --help Show this message and exit.
|
||||||
|
|
||||||
|
|
||||||
|
duplicate
|
||||||
|
=========
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
Usage: sqlite-utils duplicate [OPTIONS] PATH TABLE NEW_TABLE
|
||||||
|
|
||||||
|
Create a duplicate of this table, copying across the schema and all row data.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--load-extension TEXT SQLite extensions to load
|
||||||
|
-h, --help Show this message and exit.
|
||||||
|
|
||||||
|
|
||||||
drop-table
|
drop-table
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1476,6 +1476,15 @@ You can specify foreign key relationships between the tables you are creating us
|
||||||
|
|
||||||
If a table with the same name already exists, you will get an error. You can choose to silently ignore this error with ``--ignore``, or you can replace the existing table with a new, empty table using ``--replace``.
|
If a table with the same name already exists, you will get an error. You can choose to silently ignore this error with ``--ignore``, or you can replace the existing table with a new, empty table using ``--replace``.
|
||||||
|
|
||||||
|
.. _cli_duplicate_table:
|
||||||
|
|
||||||
|
Duplicating tables
|
||||||
|
==================
|
||||||
|
|
||||||
|
The ``duplicate`` command duplicates a table - creating a new table with the same schema and a copy of all of the rows::
|
||||||
|
|
||||||
|
$ sqlite-utils duplicate books.db authors authors_copy
|
||||||
|
|
||||||
.. _cli_drop_table:
|
.. _cli_drop_table:
|
||||||
|
|
||||||
Dropping tables
|
Dropping tables
|
||||||
|
|
|
||||||
|
|
@ -691,6 +691,8 @@ The ``table.duplicate()`` method creates a copy of the table, copying both the t
|
||||||
|
|
||||||
The new ``authors_copy`` table will now contain a duplicate copy of the data from ``authors``.
|
The new ``authors_copy`` table will now contain a duplicate copy of the data from ``authors``.
|
||||||
|
|
||||||
|
This method raises ``sqlite_utils.db.NoTable`` if the table does not exist.
|
||||||
|
|
||||||
.. _python_api_bulk_inserts:
|
.. _python_api_bulk_inserts:
|
||||||
|
|
||||||
Bulk inserts
|
Bulk inserts
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ from datetime import datetime
|
||||||
import hashlib
|
import hashlib
|
||||||
import pathlib
|
import pathlib
|
||||||
import sqlite_utils
|
import sqlite_utils
|
||||||
from sqlite_utils.db import AlterError, BadMultiValues, DescIndex
|
from sqlite_utils.db import AlterError, BadMultiValues, DescIndex, NoTable
|
||||||
from sqlite_utils.utils import maximize_csv_field_size_limit
|
from sqlite_utils.utils import maximize_csv_field_size_limit
|
||||||
from sqlite_utils import recipes
|
from sqlite_utils import recipes
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
@ -1465,6 +1465,27 @@ def create_table(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command(name="duplicate")
|
||||||
|
@click.argument(
|
||||||
|
"path",
|
||||||
|
type=click.Path(file_okay=True, dir_okay=False, allow_dash=False),
|
||||||
|
required=True,
|
||||||
|
)
|
||||||
|
@click.argument("table")
|
||||||
|
@click.argument("new_table")
|
||||||
|
@load_extension_option
|
||||||
|
def create_table(path, table, new_table, load_extension):
|
||||||
|
"""
|
||||||
|
Create a duplicate of this table, copying across the schema and all row data.
|
||||||
|
"""
|
||||||
|
db = sqlite_utils.Database(path)
|
||||||
|
_load_extensions(db, load_extension)
|
||||||
|
try:
|
||||||
|
db[table].duplicate(new_table)
|
||||||
|
except NoTable:
|
||||||
|
raise click.ClickException('Table "{}" does not exist'.format(table))
|
||||||
|
|
||||||
|
|
||||||
@cli.command(name="drop-table")
|
@cli.command(name="drop-table")
|
||||||
@click.argument(
|
@click.argument(
|
||||||
"path",
|
"path",
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
from ast import Not
|
||||||
from .utils import (
|
from .utils import (
|
||||||
chunks,
|
chunks,
|
||||||
hash_record,
|
hash_record,
|
||||||
|
|
@ -224,6 +225,11 @@ class NoObviousTable(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NoTable(Exception):
|
||||||
|
"Specified table does not exist"
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BadPrimaryKey(Exception):
|
class BadPrimaryKey(Exception):
|
||||||
"Table does not have a single obvious primary key"
|
"Table does not have a single obvious primary key"
|
||||||
pass
|
pass
|
||||||
|
|
@ -1482,7 +1488,8 @@ class Table(Queryable):
|
||||||
|
|
||||||
:param new_name: Name of the new table
|
:param new_name: Name of the new table
|
||||||
"""
|
"""
|
||||||
assert self.exists()
|
if not self.exists():
|
||||||
|
raise NoTable(f"Table {self.name} does not exist")
|
||||||
with self.db.conn:
|
with self.db.conn:
|
||||||
sql = "CREATE TABLE [{new_table}] AS SELECT * FROM [{table}];".format(
|
sql = "CREATE TABLE [{new_table}] AS SELECT * FROM [{table}];".format(
|
||||||
new_table=new_name,
|
new_table=new_name,
|
||||||
|
|
|
||||||
|
|
@ -2129,3 +2129,26 @@ def test_analyze(tmpdir, options, expected):
|
||||||
result = CliRunner().invoke(cli.cli, ["analyze", db_path] + options)
|
result = CliRunner().invoke(cli.cli, ["analyze", db_path] + options)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert list(db["sqlite_stat1"].rows) == expected
|
assert list(db["sqlite_stat1"].rows) == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_duplicate_table(tmpdir):
|
||||||
|
db_path = str(tmpdir / "test.db")
|
||||||
|
db = Database(db_path)
|
||||||
|
db["one"].insert({"id": 1, "name": "Cleo"}, pk="id")
|
||||||
|
# First try a non-existent table
|
||||||
|
result_error = CliRunner().invoke(
|
||||||
|
cli.cli,
|
||||||
|
["duplicate", db_path, "missing", "two"],
|
||||||
|
catch_exceptions=False,
|
||||||
|
)
|
||||||
|
assert result_error.exit_code == 1
|
||||||
|
assert result_error.output == 'Error: Table "missing" does not exist\n'
|
||||||
|
# Now try for a table that exists
|
||||||
|
result = CliRunner().invoke(
|
||||||
|
cli.cli,
|
||||||
|
["duplicate", db_path, "one", "two"],
|
||||||
|
catch_exceptions=False,
|
||||||
|
)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert db["one"].columns_dict == db["two"].columns_dict
|
||||||
|
assert list(db["one"].rows) == list(db["two"].rows)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
from sqlite_utils.db import NoTable
|
||||||
import datetime
|
import datetime
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
@ -38,5 +39,5 @@ def test_duplicate(fresh_db):
|
||||||
|
|
||||||
|
|
||||||
def test_duplicate_fails_if_table_does_not_exist(fresh_db):
|
def test_duplicate_fails_if_table_does_not_exist(fresh_db):
|
||||||
with pytest.raises(AssertionError):
|
with pytest.raises(NoTable):
|
||||||
fresh_db["not_a_table"].duplicate("duplicated")
|
fresh_db["not_a_table"].duplicate("duplicated")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue