stratified_packager.toolbelt.gpkg

Plugin-agnostic GeoPackage helpers: introspection, table dropping, style/metadata SQL.

Identifier and value quoting lives in the pure-stdlib sql; this module consumes it and adds the GDAL/OGR and sqlite3 work.

DO NOT import from the qgis package in this module (it must stay usable from background threads and scripts/); osgeo (GDAL/OGR), sqlite3 and the standard library only.

Style and metadata payloads are written by raw SQL exactly the way QGIS writes them; a table is dropped through OGR (DeleteLayer also cleans the gpkg system tables and the r-tree).

Functions

checkpoint_wal(gpkg, /)

Fold any WAL content into the main database file (pre-copy safety).

create_attribute_index(gpkg, table, columns, /)

Create an attribute index on columns of table (idempotent).

drop_table(gpkg, table, /)

Drop a feature table from the GeoPackage, including its system-table registrations.

feature_count(gpkg, table, /)

Count the rows of table.

geometry_column_of(gpkg, table, /)

Return the geometry column name of table, or '' for attribute-only tables.

layer_names(gpkg, /)

List the feature tables registered in a GeoPackage.

table_exists(gpkg, table, /)

Report whether table exists in the GeoPackage.

wal_session(gpkg, /)

Hold the database in WAL journal mode, with a live -wal sidecar, for the block.

write_layer_metadata(gpkg, /, *, table, qmd_xml)

Insert a QGIS layer-metadata (QMD) document for table into the GeoPackage.

write_layer_style(gpkg, /, *, table, ...[, ...])

Insert one named style row into the GeoPackage's layer_styles table.

stratified_packager.toolbelt.gpkg._connect_readonly(gpkg)[source]

Open a read-only connection (a plain connect would create a missing file).

Parameters:

gpkg (Path) – GeoPackage path (must exist).

Return type:

Connection

Returns:

The read-only connection.

stratified_packager.toolbelt.gpkg.checkpoint_wal(gpkg, /)[source]

Fold any WAL content into the main database file (pre-copy safety).

A GeoPackage that some connection switched to WAL journal mode (e.g. QGIS/OGR reads) carries -wal/-shm sidecars; copying or zipping only the main file would then ship a stale database. wal_checkpoint(TRUNCATE) moves every committed frame into the main file and zeroes the WAL, after which the main file is complete on its own. The follow-up journal_mode=DELETE tidies the sidecars away entirely but needs exclusive access, so its failure (another connection still holds the file) is ignored — a fully checkpointed WAL-mode file without its sidecars is still a valid, complete database.

Parameters:

gpkg (Path) – GeoPackage path (a missing file is a successful no-op).

Return type:

bool

Returns:

Whether the checkpoint completed (False = busy/locked; the main file may be stale and the caller should surface it).

stratified_packager.toolbelt.gpkg.create_attribute_index(gpkg, table, columns, /)[source]

Create an attribute index on columns of table (idempotent).

Speeds the per-stratum key filter (key_fields IN (...)) the GeoPackage provider pushes down when a staged copy is read once per stratum. A single multi-column index serves both the single-field IN and the composite-key equality forms. A no-op when columns is empty or the index already exists.

Parameters:
  • gpkg (Path) – GeoPackage path (the caller must be its only writer).

  • table (str) – Feature table to index.

  • columns (Sequence[str]) – The columns to index, in query order (empty = no-op).

Return type:

None

stratified_packager.toolbelt.gpkg.drop_table(gpkg, table, /)[source]

Drop a feature table from the GeoPackage, including its system-table registrations.

Delegates to OGR’s DeleteLayer, which cleans gpkg_contents, gpkg_geometry_columns, the r-tree index tables and the OGR feature-count side table along with the table itself.

Parameters:
  • gpkg (Path) – GeoPackage path (the caller must be its only writer).

  • table (str) – Table name.

Return type:

bool

Returns:

True if the table existed and was dropped.

stratified_packager.toolbelt.gpkg.feature_count(gpkg, table, /)[source]

Count the rows of table.

Parameters:
  • gpkg (Path) – GeoPackage path (must exist).

  • table (str) – Table name (must exist).

Return type:

int

Returns:

The row count.

stratified_packager.toolbelt.gpkg.geometry_column_of(gpkg, table, /)[source]

Return the geometry column name of table, or '' for attribute-only tables.

Parameters:
  • gpkg (Path) – GeoPackage path.

  • table (str) – Table name.

Return type:

str

Returns:

The gpkg_geometry_columns entry, or an empty string.

stratified_packager.toolbelt.gpkg.layer_names(gpkg, /)[source]

List the feature tables registered in a GeoPackage.

Parameters:

gpkg (Path) – GeoPackage path.

Return type:

list[str]

Returns:

gpkg_contents table names with data_type = 'features', sorted; empty when the file does not exist.

stratified_packager.toolbelt.gpkg.table_exists(gpkg, table, /)[source]

Report whether table exists in the GeoPackage.

Parameters:
  • gpkg (Path) – GeoPackage path (a missing file reports False).

  • table (str) – Table name.

Return type:

bool

Returns:

True if present in sqlite_master.

stratified_packager.toolbelt.gpkg.wal_session(gpkg, /)[source]

Hold the database in WAL journal mode, with a live -wal sidecar, for the block.

A reader that opens a SQLite file in nolock mode (as QGIS’s OGR connection pool does for read-only GeoPackage opens) fails mid-statement when another connection materializes the -wal sidecar afterwards — but an open against a file whose sidecar already exists is detected and cleanly retried without nolock. Merely flipping the journal mode is not enough: closing the flipping connection auto-checkpoints and removes the sidecar again, so later opens still go nolock. This context manager therefore switches to WAL, materializes the sidecar with a no-op gpkg_contents touch (a plain table: no r-tree triggers fire), and keeps its connection open so the sidecar outlives every open made inside the block; checkpoint_wal() reverts the file before it is copied or zipped.

Parameters:

gpkg (Path) – GeoPackage path.

Yield:

Whether the file is now held in WAL journal mode (False = missing file or a SQLite error; the caller may proceed — the session is log-hygiene, not correctness).

stratified_packager.toolbelt.gpkg.write_layer_metadata(gpkg, /, *, table, qmd_xml)[source]

Insert a QGIS layer-metadata (QMD) document for table into the GeoPackage.

Creates the gpkg_metadata / gpkg_metadata_reference tables and their gpkg_extensions registrations when missing, then inserts the metadata row (scope dataset, QGIS standard URI) and its table-scoped reference, mirroring how QGIS itself stores metadata.

Parameters:
  • gpkg (Path) – GeoPackage path (the caller must be its only writer).

  • table (str) – Feature table the metadata describes.

  • qmd_xml (str) – The QMD XML document.

Return type:

None

stratified_packager.toolbelt.gpkg.write_layer_style(gpkg, /, *, table, geometry_column, style_name, qml, sld='', use_as_default=False, description='')[source]

Insert one named style row into the GeoPackage’s layer_styles table.

Creates the table and its gpkg_contents registration (data type attributes) when missing, mirroring how QGIS itself stores styles.

Parameters:
  • gpkg (Path) – GeoPackage path (the caller must be its only writer).

  • table (str) – Feature table the style applies to.

  • geometry_column (str) – The table’s geometry column (empty for attribute tables).

  • style_name (str) – Style name shown in QGIS’ style manager.

  • qml (str) – Full QML document.

  • sld (str) – Optional SLD document (QGIS fills both; SLD is best-effort here).

  • use_as_default (bool) – Whether QGIS should load this style by default.

  • description (str) – Optional style description.

Return type:

None

stratified_packager.toolbelt.gpkg._GPKG_METADATA_DDL: Final = "\nCREATE TABLE IF NOT EXISTS gpkg_metadata (\n  id INTEGER CONSTRAINT m_pk PRIMARY KEY ASC NOT NULL,\n  md_scope TEXT NOT NULL DEFAULT 'dataset',\n  md_standard_uri TEXT NOT NULL,\n  mime_type TEXT NOT NULL DEFAULT 'text/xml',\n  metadata TEXT NOT NULL DEFAULT ''\n)\n"

gpkg_metadata DDL per the GeoPackage metadata extension.

stratified_packager.toolbelt.gpkg._GPKG_METADATA_REFERENCE_DDL: Final = "\nCREATE TABLE IF NOT EXISTS gpkg_metadata_reference (\n  reference_scope TEXT NOT NULL,\n  table_name TEXT,\n  column_name TEXT,\n  row_id_value INTEGER,\n  timestamp DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),\n  md_file_id INTEGER NOT NULL,\n  md_parent_id INTEGER,\n  CONSTRAINT crmr_mfi_fk FOREIGN KEY (md_file_id) REFERENCES gpkg_metadata(id),\n  CONSTRAINT crmr_mpi_fk FOREIGN KEY (md_parent_id) REFERENCES gpkg_metadata(id)\n)\n"

gpkg_metadata_reference DDL per the GeoPackage metadata extension.

stratified_packager.toolbelt.gpkg._LAYER_STYLES_DDL: Final = '\nCREATE TABLE IF NOT EXISTS "layer_styles" (\n  "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n  "f_table_catalog" TEXT(256),\n  "f_table_schema" TEXT(256),\n  "f_table_name" TEXT(256),\n  "f_geometry_column" TEXT(256),\n  "styleName" TEXT(30),\n  "styleQML" TEXT,\n  "styleSLD" TEXT,\n  "useAsDefault" BOOLEAN,\n  "description" TEXT,\n  "owner" TEXT(30),\n  "ui" TEXT(30),\n  "update_time" DATETIME DEFAULT (strftime(\'%Y-%m-%dT%H:%M:%fZ\',\'now\'))\n)\n'

layer_styles DDL exactly as QGIS creates it (captured from a 4.0.3-written gpkg).

stratified_packager.toolbelt.gpkg._QGIS_METADATA_STANDARD_URI: Final = 'http://mrcc.com/qgis.dtd'

md_standard_uri QGIS stamps on its layer-metadata rows.