diff --git a/README.md b/README.md index e04ca33..102a7bb 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,8 @@ For PostgreSQL, use this: --version Show the version and exit. --all Detect and copy all tables --table TEXT Specific tables to copy - --skip TEXT When using --all skip these tables + --table-name-pattern TEXT Table name pattern for tables to copy + --skip TEXT When using --all or --table-name-pattern skip these tables --redact TEXT... (table, column) pairs to redact with *** --sql TEXT Optional SQL query to run --output TEXT Table in which to save --sql query results @@ -67,7 +68,12 @@ You can also save the data from all of your tables, effectively creating a SQLit db-to-sqlite "postgresql://localhost/myblog" blog.db \ --all -When running `--all` you can specify tables to skip using `--skip`: +Alternatively, you can specify a regex pattern via `--table-name-pattern` to match against table names. For example: + + db-to-sqlite "postgresql://localhost/myblog" blog.db \ + --table-name-pattern "tag_\w+" + +When running `--all` or `--table-name-pattern` you can specify tables to skip using `--skip`: db-to-sqlite "postgresql://localhost/myblog" blog.db \ --all \ diff --git a/db_to_sqlite/cli.py b/db_to_sqlite/cli.py index cdb3037..5bf2b03 100644 --- a/db_to_sqlite/cli.py +++ b/db_to_sqlite/cli.py @@ -1,4 +1,5 @@ import itertools +import re import click from sqlalchemy import create_engine, inspect @@ -11,7 +12,8 @@ @click.argument("path", type=click.Path(exists=False), required=True) @click.option("--all", help="Detect and copy all tables", is_flag=True) @click.option("--table", help="Specific tables to copy", multiple=True) -@click.option("--skip", help="When using --all skip these tables", multiple=True) +@click.option("--table-name-pattern", help="Table name pattern for tables to copy") +@click.option("--skip", help="When using --all or --table-name-pattern skip these tables", multiple=True) @click.option( "--redact", help="(table, column) pairs to redact with ***", @@ -34,6 +36,7 @@ def cli( path, all, table, + table_name_pattern, skip, redact, sql, @@ -58,10 +61,14 @@ def cli( More: https://docs.sqlalchemy.org/en/13/core/engines.html#database-urls """ - if not all and not table and not sql: - raise click.ClickException("--all OR --table OR --sql required") - if skip and not all: - raise click.ClickException("--skip can only be used with --all") + if not all and not table and not table_name_pattern and not sql: + raise click.ClickException( + "--all OR --table OR --table-name-pattern OR --sql required" + ) + if skip and not (all or table_name_pattern): + raise click.ClickException( + "--skip can only be used with --all OR --table-name-pattern" + ) redact_columns = {} for table_name, column_name in redact: redact_columns.setdefault(table_name, set()).add(column_name) @@ -78,6 +85,12 @@ def cli( tables = table if all: tables = inspector.get_table_names() + elif table_name_pattern: + tables = [ + t + for t in inspector.get_table_names() + if re.match(table_name_pattern, t) is not None + ] if tables: foreign_keys_to_add = [] for i, table in enumerate(tables):