Skip to content

Google Cloud Spanner Data Dictionary & SQL Catalog

from sqlspec.data_dictionary import get_data_dictionary_loader, get_dialect_config

config = get_dialect_config("spanner")

Provides dual SQL catalog packs (googlesql and postgresql) introspecting INFORMATION_SCHEMA tables, columns, indexes (STORING, SEARCH, VECTOR), foreign keys, parent-child interleaving, and row deletion policies. See the Google Cloud Spanner Guide and Data Dictionary Guide for usage examples.

Dialect Configuration

Setting Value
Dialect Name spanner
Default Schema None
Version Pattern .*
DDL Strategy AST synthesis with INTERLEAVE IN PARENT & ROW DELETION POLICY (GoogleSQL & PostgreSQL modes)
Catalog .sql Files 5 files (8 named queries)

Capabilities & Type Mappings

Capability Status / Minimum Version Logical Type Target Physical Type
supports_for_update False array ARRAY
supports_generators False bigint INT64
supports_index_clustering True bignumeric NUMERIC
supports_interleaved_tables True blob BYTES(MAX)
supports_json True boolean BOOL
supports_on_conflict True float FLOAT64
supports_skip_locked False float32 FLOAT32
supports_update_from False integer INT64
- - json JSON
- - numeric NUMERIC
- - text STRING(MAX)
- - timestamp TIMESTAMP
- - tokenlist TOKENLIST
- - uuid BYTES(16)
- - varchar STRING({length})

Adapter Data Dictionary Classes

SpannerSyncDataDictionary

SpannerSyncDataDictionary(mode: str = 'googlesql')

Bases: SyncDataDictionaryBase

Fetch table, column, and index metadata from Spanner.

Methods:

Name Description
get_query

Return an exact domain query for this dialect.

get_version

Get Spanner version information.

get_feature_flag

Check if Spanner supports a specific feature.

get_optimal_type

Get optimal Spanner type for a category.

get_tables

Get tables using INFORMATION_SCHEMA.

get_columns

Get column information for a table or schema.

get_indexes

Get index metadata for a table or schema.

get_foreign_keys

Get foreign key metadata.

get_constraints

Get constraint metadata for a table or schema.

get_sequences

Get sequence metadata.

get_change_streams

Get change stream metadata.

get_system_metadata

Get opt-in Spanner system metadata from SPANNER_SYS.

get_metadata_capabilities

Get Spanner data-dictionary capability profile.

Attributes:

Name Type Description
dialect str
mode

get_query

get_query(domain: str, operation: str, *, mode: str | None = None) -> SQL

Return an exact domain query for this dialect.

get_version

get_version(driver: SpannerSyncDriver | None = None) -> VersionInfo | None

Get Spanner version information.

Parameters:

Name Type Description Default
driver SpannerSyncDriver | None

Spanner driver instance.

None

Returns:

Type Description
VersionInfo | None

None since Spanner does not expose version information.

get_feature_flag

get_feature_flag(
    driver: SpannerSyncDriver | None = None, feature: str = ""
) -> bool

Check if Spanner supports a specific feature.

Parameters:

Name Type Description Default
driver SpannerSyncDriver | None

Spanner driver instance.

None
feature str

Feature name to check.

''

Returns:

Type Description
bool

True if feature is supported, False otherwise.

get_optimal_type

get_optimal_type(
    driver: SpannerSyncDriver | None = None, type_category: str = ""
) -> str

Get optimal Spanner type for a category.

Parameters:

Name Type Description Default
driver SpannerSyncDriver | None

Spanner driver instance.

None
type_category str

Type category.

''

Returns:

Type Description
str

Spanner-specific type name.

get_tables

get_tables(
    driver: SpannerSyncDriver, schema: str | None = None
) -> list[TableMetadata]

Get tables using INFORMATION_SCHEMA.

get_columns

get_columns(
    driver: SpannerSyncDriver,
    table: str | None = None,
    schema: str | None = None,
) -> list[ColumnMetadata]

Get column information for a table or schema.

get_indexes

get_indexes(
    driver: SpannerSyncDriver,
    table: str | None = None,
    schema: str | None = None,
) -> list[IndexMetadata]

Get index metadata for a table or schema.

get_foreign_keys

get_foreign_keys(
    driver: SpannerSyncDriver,
    table: str | None = None,
    schema: str | None = None,
) -> list[ForeignKeyMetadata]

Get foreign key metadata.

get_constraints

get_constraints(
    driver: SpannerSyncDriver,
    table: str | None = None,
    schema: str | None = None,
) -> MetadataResult

Get constraint metadata for a table or schema.

get_sequences

get_sequences(
    driver: SpannerSyncDriver,
    schema: str | None = None,
    sequence_name: str | None = None,
) -> MetadataResult

Get sequence metadata.

get_change_streams

get_change_streams(
    driver: SpannerSyncDriver,
    schema: str | None = None,
    stream_name: str | None = None,
) -> MetadataResult

Get change stream metadata.

get_system_metadata

get_system_metadata(
    driver: SpannerSyncDriver,
    request: SystemMetadataRequest | str | None = None,
    **kwargs: Any,
) -> SystemMetadataResult

Get opt-in Spanner system metadata from SPANNER_SYS.

get_metadata_capabilities

get_metadata_capabilities(
    driver: Any,
    domains: Sequence[str] | None = None,
    *,
    mode: str | None = None,
) -> MetadataCapabilityProfile

Get Spanner data-dictionary capability profile.

SpannerAsyncDataDictionary

SpannerAsyncDataDictionary(mode: str = 'googlesql')

Bases: AsyncDataDictionaryBase

Fetch table, column, and index metadata from Spanner.

Methods:

Name Description
get_query

Return an exact domain query for this dialect.

get_version

Get Spanner version information.

get_feature_flag

Check if Spanner supports a specific feature.

get_optimal_type

Get optimal Spanner type for a category.

get_tables

Get tables using INFORMATION_SCHEMA.

get_columns

Get column information for a table or schema.

get_indexes

Get index metadata for a table or schema.

get_foreign_keys

Get foreign key metadata.

get_constraints

Get constraint metadata for a table or schema.

get_sequences

Get sequence metadata.

get_change_streams

Get change stream metadata.

get_system_metadata

Get opt-in Spanner system metadata from SPANNER_SYS.

get_metadata_capabilities

Get Spanner data-dictionary capability profile.

Attributes:

Name Type Description
dialect str
mode

get_query

get_query(domain: str, operation: str, *, mode: str | None = None) -> SQL

Return an exact domain query for this dialect.

get_version async

get_version(driver: SpannerAsyncDriver | None = None) -> VersionInfo | None

Get Spanner version information.

Parameters:

Name Type Description Default
driver SpannerAsyncDriver | None

Async Spanner driver instance.

None

Returns:

Type Description
VersionInfo | None

None since Spanner does not expose version information.

get_feature_flag async

get_feature_flag(
    driver: SpannerAsyncDriver | None = None, feature: str = ""
) -> bool

Check if Spanner supports a specific feature.

Parameters:

Name Type Description Default
driver SpannerAsyncDriver | None

Async Spanner driver instance.

None
feature str

Feature name to check.

''

Returns:

Type Description
bool

True if feature is supported, False otherwise.

get_optimal_type async

get_optimal_type(
    driver: SpannerAsyncDriver | None = None, type_category: str = ""
) -> str

Get optimal Spanner type for a category.

Parameters:

Name Type Description Default
driver SpannerAsyncDriver | None

Async Spanner driver instance.

None
type_category str

Type category.

''

Returns:

Type Description
str

Spanner-specific type name.

get_tables async

get_tables(
    driver: SpannerAsyncDriver, schema: str | None = None
) -> list[TableMetadata]

Get tables using INFORMATION_SCHEMA.

get_columns async

get_columns(
    driver: SpannerAsyncDriver,
    table: str | None = None,
    schema: str | None = None,
) -> list[ColumnMetadata]

Get column information for a table or schema.

get_indexes async

get_indexes(
    driver: SpannerAsyncDriver,
    table: str | None = None,
    schema: str | None = None,
) -> list[IndexMetadata]

Get index metadata for a table or schema.

get_foreign_keys async

get_foreign_keys(
    driver: SpannerAsyncDriver,
    table: str | None = None,
    schema: str | None = None,
) -> list[ForeignKeyMetadata]

Get foreign key metadata.

get_constraints async

get_constraints(
    driver: SpannerAsyncDriver,
    table: str | None = None,
    schema: str | None = None,
) -> MetadataResult

Get constraint metadata for a table or schema.

get_sequences async

get_sequences(
    driver: SpannerAsyncDriver,
    schema: str | None = None,
    sequence_name: str | None = None,
) -> MetadataResult

Get sequence metadata.

get_change_streams async

get_change_streams(
    driver: SpannerAsyncDriver,
    schema: str | None = None,
    stream_name: str | None = None,
) -> MetadataResult

Get change stream metadata.

get_system_metadata async

get_system_metadata(
    driver: SpannerAsyncDriver,
    request: SystemMetadataRequest | str | None = None,
    **kwargs: Any,
) -> SystemMetadataResult

Get opt-in Spanner system metadata from SPANNER_SYS.

get_metadata_capabilities async

get_metadata_capabilities(
    driver: Any,
    domains: Sequence[str] | None = None,
    *,
    mode: str | None = None,
) -> MetadataCapabilityProfile

Get Spanner data-dictionary capability profile.

Catalog SQL Queries

The spanner dialect pack defines 8 named queries across 5 domain .sql files loaded via DataDictionaryLoader (sqlspec/data_dictionary/dialects/spanner/):

Domain Pack Named Queries Bind Parameters
columns.sql by_table, by_schema :schema_name, :table_name
foreign_keys.sql by_table, by_schema :schema_name, :table_name
indexes.sql by_table, by_schema :schema_name, :table_name
tables.sql by_schema :schema_name
version.sql current none
columns.sql (2 named queries)
-- name: by_table
-- dialect: spanner
WITH pk_cols AS (
    SELECT
        ic.table_schema,
        ic.table_name,
        ic.column_name
    FROM information_schema.index_columns AS ic
    WHERE ic.index_name = 'PRIMARY_KEY'
      AND ic.table_name = :table_name
      AND (CAST(:schema_name AS STRING) IS NULL OR ic.table_schema = :schema_name)
)
SELECT
    c.column_name,
    c.spanner_type AS data_type,
    c.is_nullable,
    c.column_default,
    CASE WHEN pk_cols.column_name IS NOT NULL THEN TRUE ELSE FALSE END AS is_primary,
    CASE WHEN c.is_identity = 'YES' THEN TRUE ELSE FALSE END AS is_identity,
    CASE WHEN c.is_generated = 'ALWAYS' OR c.generation_expression IS NOT NULL THEN TRUE ELSE FALSE END AS is_generated,
    c.generation_expression
FROM information_schema.columns AS c
LEFT JOIN pk_cols
    ON c.table_schema = pk_cols.table_schema
    AND c.table_name = pk_cols.table_name
    AND c.column_name = pk_cols.column_name
WHERE c.table_name = :table_name
  AND (CAST(:schema_name AS STRING) IS NULL OR c.table_schema = :schema_name)
ORDER BY c.ordinal_position;

-- name: by_schema
-- dialect: spanner
WITH pk_cols AS (
    SELECT
        ic.table_schema,
        ic.table_name,
        ic.column_name
    FROM information_schema.index_columns AS ic
    WHERE ic.index_name = 'PRIMARY_KEY'
      AND (CAST(:schema_name AS STRING) IS NULL OR ic.table_schema = :schema_name)
)
SELECT
    c.table_name,
    c.column_name,
    c.spanner_type AS data_type,
    c.is_nullable,
    c.column_default,
    CASE WHEN pk_cols.column_name IS NOT NULL THEN TRUE ELSE FALSE END AS is_primary,
    CASE WHEN c.is_identity = 'YES' THEN TRUE ELSE FALSE END AS is_identity,
    CASE WHEN c.is_generated = 'ALWAYS' OR c.generation_expression IS NOT NULL THEN TRUE ELSE FALSE END AS is_generated,
    c.generation_expression
FROM information_schema.columns AS c
LEFT JOIN pk_cols
    ON c.table_schema = pk_cols.table_schema
    AND c.table_name = pk_cols.table_name
    AND c.column_name = pk_cols.column_name
WHERE (CAST(:schema_name AS STRING) IS NULL OR c.table_schema = :schema_name)
ORDER BY c.table_name, c.ordinal_position;
foreign_keys.sql (2 named queries)
-- name: by_table
-- dialect: spanner
WITH fk_constraints AS (
    SELECT
        constraint_name,
        unique_constraint_name
    FROM information_schema.referential_constraints
    WHERE (CAST(:schema_name AS STRING) IS NULL OR constraint_schema = :schema_name)
),
fk_columns AS (
    SELECT
        constraint_name,
        table_name,
        column_name,
        ordinal_position,
        table_schema
    FROM information_schema.key_column_usage
    WHERE (CAST(:schema_name AS STRING) IS NULL OR constraint_schema = :schema_name)
      AND (CAST(:table_name AS STRING) IS NULL OR table_name = :table_name)
),
pk_columns AS (
    SELECT
        constraint_name,
        table_name,
        column_name,
        ordinal_position,
        table_schema
    FROM information_schema.key_column_usage
    WHERE (CAST(:schema_name AS STRING) IS NULL OR constraint_schema = :schema_name)
)
SELECT
    fk.table_name,
    fk.column_name,
    pk.table_name AS referenced_table_name,
    pk.column_name AS referenced_column_name,
    fk.constraint_name,
    fk.table_schema AS table_schema,
    pk.table_schema AS referenced_table_schema
FROM fk_columns fk
JOIN fk_constraints rc
  ON fk.constraint_name = rc.constraint_name
JOIN pk_columns pk
  ON pk.constraint_name = rc.unique_constraint_name
  AND pk.ordinal_position = fk.ordinal_position
WHERE (CAST(:table_name AS STRING) IS NULL OR fk.table_name = :table_name)
ORDER BY fk.table_name, fk.ordinal_position;

-- name: by_schema
-- dialect: spanner
WITH fk_constraints AS (
    SELECT
        constraint_name,
        unique_constraint_name
    FROM information_schema.referential_constraints
    WHERE (CAST(:schema_name AS STRING) IS NULL OR constraint_schema = :schema_name)
),
fk_columns AS (
    SELECT
        constraint_name,
        table_name,
        column_name,
        ordinal_position,
        table_schema
    FROM information_schema.key_column_usage
    WHERE (CAST(:schema_name AS STRING) IS NULL OR constraint_schema = :schema_name)
),
pk_columns AS (
    SELECT
        constraint_name,
        table_name,
        column_name,
        ordinal_position,
        table_schema
    FROM information_schema.key_column_usage
    WHERE (CAST(:schema_name AS STRING) IS NULL OR constraint_schema = :schema_name)
)
SELECT
    fk.table_name,
    fk.column_name,
    pk.table_name AS referenced_table_name,
    pk.column_name AS referenced_column_name,
    fk.constraint_name,
    fk.table_schema AS table_schema,
    pk.table_schema AS referenced_table_schema
FROM fk_columns fk
JOIN fk_constraints rc
  ON fk.constraint_name = rc.constraint_name
JOIN pk_columns pk
  ON pk.constraint_name = rc.unique_constraint_name
  AND pk.ordinal_position = fk.ordinal_position
ORDER BY fk.table_name, fk.ordinal_position;
indexes.sql (2 named queries)
-- name: by_table
-- dialect: spanner
SELECT
    i.index_name,
    i.table_name,
    i.is_unique AS is_unique,
    i.is_primary_key AS is_primary,
    ARRAY_AGG(ic.column_name ORDER BY ic.ordinal_position) AS columns
FROM information_schema.indexes i
JOIN information_schema.index_columns ic
  ON i.index_name = ic.index_name
  AND i.table_name = ic.table_name
WHERE i.table_name = :table_name
  AND (CAST(:schema_name AS STRING) IS NULL OR i.table_schema = :schema_name)
GROUP BY i.index_name, i.table_name, i.is_unique, i.is_primary_key;

-- name: by_schema
-- dialect: spanner
SELECT
    i.index_name,
    i.table_name,
    i.is_unique AS is_unique,
    i.is_primary_key AS is_primary,
    ARRAY_AGG(ic.column_name ORDER BY ic.ordinal_position) AS columns
FROM information_schema.indexes i
JOIN information_schema.index_columns ic
  ON i.index_name = ic.index_name
  AND i.table_name = ic.table_name
WHERE (CAST(:schema_name AS STRING) IS NULL OR i.table_schema = :schema_name)
GROUP BY i.index_name, i.table_name, i.is_unique, i.is_primary_key;
tables.sql (1 named queries)
-- name: by_schema
-- dialect: spanner
SELECT
    table_name,
    0 AS level
FROM information_schema.tables
WHERE table_type = 'BASE TABLE'
  AND (CAST(:schema_name AS STRING) IS NULL OR table_schema = :schema_name)
ORDER BY table_name;
version.sql (1 named queries)
-- name: current
-- dialect: spanner
SELECT NULL AS version;