mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-07-23 01:14:31 +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.
|
||||
|
||||
|
||||
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
|
||||
==========
|
||||
|
||||
|
|
|
|||
|
|
@ -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``.
|
||||
|
||||
.. _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:
|
||||
|
||||
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``.
|
||||
|
||||
This method raises ``sqlite_utils.db.NoTable`` if the table does not exist.
|
||||
|
||||
.. _python_api_bulk_inserts:
|
||||
|
||||
Bulk inserts
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from datetime import datetime
|
|||
import hashlib
|
||||
import pathlib
|
||||
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 import recipes
|
||||
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")
|
||||
@click.argument(
|
||||
"path",
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from ast import Not
|
||||
from .utils import (
|
||||
chunks,
|
||||
hash_record,
|
||||
|
|
@ -224,6 +225,11 @@ class NoObviousTable(Exception):
|
|||
pass
|
||||
|
||||
|
||||
class NoTable(Exception):
|
||||
"Specified table does not exist"
|
||||
pass
|
||||
|
||||
|
||||
class BadPrimaryKey(Exception):
|
||||
"Table does not have a single obvious primary key"
|
||||
pass
|
||||
|
|
@ -1482,7 +1488,8 @@ class Table(Queryable):
|
|||
|
||||
: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:
|
||||
sql = "CREATE TABLE [{new_table}] AS SELECT * FROM [{table}];".format(
|
||||
new_table=new_name,
|
||||
|
|
|
|||
|
|
@ -2129,3 +2129,26 @@ def test_analyze(tmpdir, options, expected):
|
|||
result = CliRunner().invoke(cli.cli, ["analyze", db_path] + options)
|
||||
assert result.exit_code == 0
|
||||
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 pytest
|
||||
|
||||
|
|
@ -38,5 +39,5 @@ def test_duplicate(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")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue