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
¶
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
¶
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;