mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-09-19 23:14:09 +02:00
db.schema and 'sqlite-utils schema' command, closes #268
This commit is contained in:
parent
9696abfabf
commit
0d2e4f49f3
6 changed files with 90 additions and 2 deletions
13
docs/cli.rst
13
docs/cli.rst
|
|
@ -348,6 +348,19 @@ It defaults to showing triggers for all tables. To see triggers for one or more
|
||||||
|
|
||||||
The command takes the same format options as the ``tables`` and ``views`` commands.
|
The command takes the same format options as the ``tables`` and ``views`` commands.
|
||||||
|
|
||||||
|
.. _cli_schema:
|
||||||
|
|
||||||
|
Showing the schema
|
||||||
|
==================
|
||||||
|
|
||||||
|
The ``sqlite-utils schema`` command shows the full SQL schema for the database::
|
||||||
|
|
||||||
|
$ sqlite-utils schema dogs.db
|
||||||
|
CREATE TABLE "dogs" (
|
||||||
|
[id] INTEGER PRIMARY KEY,
|
||||||
|
[name] TEXT
|
||||||
|
);
|
||||||
|
|
||||||
.. _cli_analyze_tables:
|
.. _cli_analyze_tables:
|
||||||
|
|
||||||
Analyzing tables
|
Analyzing tables
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,21 @@ If the record does not exist a ``NotFoundError`` will be raised:
|
||||||
except NotFoundError:
|
except NotFoundError:
|
||||||
print("Dog not found")
|
print("Dog not found")
|
||||||
|
|
||||||
|
.. _python_api_schema:
|
||||||
|
|
||||||
|
Showing the schema
|
||||||
|
==================
|
||||||
|
|
||||||
|
The ``db.schema`` property returns the full SQL schema for the database as a string::
|
||||||
|
|
||||||
|
>>> db = sqlite_utils.Database("dogs.db")
|
||||||
|
>>> print(db.schema)
|
||||||
|
>>> print(db.schema)
|
||||||
|
CREATE TABLE "dogs" (
|
||||||
|
[id] INTEGER PRIMARY KEY,
|
||||||
|
[name] TEXT
|
||||||
|
);
|
||||||
|
|
||||||
.. _python_api_creating_tables:
|
.. _python_api_creating_tables:
|
||||||
|
|
||||||
Creating tables
|
Creating tables
|
||||||
|
|
|
||||||
|
|
@ -1348,6 +1348,23 @@ def indexes(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command()
|
||||||
|
@click.argument(
|
||||||
|
"path",
|
||||||
|
type=click.Path(file_okay=True, dir_okay=False, allow_dash=False),
|
||||||
|
required=True,
|
||||||
|
)
|
||||||
|
@load_extension_option
|
||||||
|
def schema(
|
||||||
|
path,
|
||||||
|
load_extension,
|
||||||
|
):
|
||||||
|
"Show full schema for this database"
|
||||||
|
db = sqlite_utils.Database(path)
|
||||||
|
_load_extensions(db, load_extension)
|
||||||
|
click.echo(db.schema)
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@click.argument(
|
@click.argument(
|
||||||
"path",
|
"path",
|
||||||
|
|
|
||||||
|
|
@ -301,6 +301,18 @@ class Database:
|
||||||
"Returns {trigger_name: sql} dictionary"
|
"Returns {trigger_name: sql} dictionary"
|
||||||
return {trigger.name: trigger.sql for trigger in self.triggers}
|
return {trigger.name: trigger.sql for trigger in self.triggers}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def schema(self):
|
||||||
|
sqls = []
|
||||||
|
for row in self.execute(
|
||||||
|
"select sql from sqlite_master where sql is not null"
|
||||||
|
).fetchall():
|
||||||
|
sql = row[0]
|
||||||
|
if not sql.strip().endswith(";"):
|
||||||
|
sql += ";"
|
||||||
|
sqls.append(sql)
|
||||||
|
return "\n".join(sqls)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def journal_mode(self):
|
def journal_mode(self):
|
||||||
return self.execute("PRAGMA journal_mode;").fetchone()[0]
|
return self.execute("PRAGMA journal_mode;").fetchone()[0]
|
||||||
|
|
|
||||||
|
|
@ -1916,6 +1916,33 @@ def test_triggers(tmpdir, extra_args, expected):
|
||||||
assert result.output == expected
|
assert result.output == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_schema(tmpdir):
|
||||||
|
db_path = str(tmpdir / "test.db")
|
||||||
|
db = Database(db_path)
|
||||||
|
db["dogs"].create({"id": int, "name": str})
|
||||||
|
db["chickens"].create({"id": int, "name": str, "breed": str})
|
||||||
|
db["chickens"].create_index(["breed"])
|
||||||
|
result = CliRunner().invoke(
|
||||||
|
cli.cli,
|
||||||
|
["schema", db_path],
|
||||||
|
catch_exceptions=False,
|
||||||
|
)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert result.output == (
|
||||||
|
"CREATE TABLE [dogs] (\n"
|
||||||
|
" [id] INTEGER,\n"
|
||||||
|
" [name] TEXT\n"
|
||||||
|
");\n"
|
||||||
|
"CREATE TABLE [chickens] (\n"
|
||||||
|
" [id] INTEGER,\n"
|
||||||
|
" [name] TEXT,\n"
|
||||||
|
" [breed] TEXT\n"
|
||||||
|
");\n"
|
||||||
|
"CREATE INDEX [idx_chickens_breed]\n"
|
||||||
|
" ON [chickens] ([breed]);\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_long_csv_column_value(tmpdir):
|
def test_long_csv_column_value(tmpdir):
|
||||||
db_path = str(tmpdir / "test.db")
|
db_path = str(tmpdir / "test.db")
|
||||||
csv_path = str(tmpdir / "test.csv")
|
csv_path = str(tmpdir / "test.csv")
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,12 @@ def test_columns(existing_db):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_schema(existing_db):
|
def test_table_schema(existing_db):
|
||||||
assert "CREATE TABLE foo (text TEXT)" == existing_db["foo"].schema
|
assert existing_db["foo"].schema == "CREATE TABLE foo (text TEXT)"
|
||||||
|
|
||||||
|
|
||||||
|
def test_database_schema(existing_db):
|
||||||
|
assert existing_db.schema == "CREATE TABLE foo (text TEXT);"
|
||||||
|
|
||||||
|
|
||||||
def test_table_repr(fresh_db):
|
def test_table_repr(fresh_db):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue