Skip to content

Datatype conversion

Datatype conversion converts native source database types (e.g. VARCHAR(255) from SQL Server) to target platform types (e.g. STRING for Databricks, StringType() for PySpark). When active, every field record in hierarchical exports and direct field results gains a datatype_converted property.

Terminal window
katalogue dataset get <id> --include-children --datatype-converter sqlserver-to-databricks --format json
katalogue datasource export <id> --datatype-converter postgres-to-databricks --template column-mapping
katalogue system export <id> --datatype-converter db2-to-pyspark --split-by dataset --output-dir ./out

--datatype-converter is available on all get and export commands.

from katalogue import KatalogueClient, GetOptions
result = client.get("system", GetOptions(
resource_id=1,
include_children=True,
datatype_converter="sqlserver-to-databricks",
))
# Each field dict in result.data["fields"] now has "datatype_converted"
for field in result.data["fields"]:
print(field["field_name"], field["datatype_fullname"], "->", field.get("datatype_converted"))
# The same conversion also applies to field get/list responses
field = client.get("field", GetOptions(resource_id=123, datatype_converter="sqlserver-to-databricks"))
print(field.data["datatype_converted"])
NameSourceTarget
sqlserver-to-databricksSQL ServerDatabricks SQL (STRING, INT, TIMESTAMP_LTZ, …)
sqlserver-to-pysparkSQL ServerPySpark types (StringType(), IntegerType(), TimestampType(), …)
db2-to-databricksIBM DB2Databricks SQL
db2-to-pysparkIBM DB2PySpark types
postgres-to-databricksPostgreSQLDatabricks SQL
postgres-to-pysparkPostgreSQLPySpark types

Built-in mappings distinguish timezone-aware from timezone-naive source types:

Source typeDatabricks targetPySpark target
DATETIMEOFFSET (SQL Server)TIMESTAMP_LTZTimestampType()
DATETIME, DATETIME2, SMALLDATETIMETIMESTAMP_NTZTimestampNTZType()
TIMESTAMP (DB2, standard)TIMESTAMP_NTZTimestampNTZType()
TIMESTAMPTZ (PostgreSQL)TIMESTAMP_LTZTimestampType()
TIMESTAMP (PostgreSQL)TIMESTAMP_NTZTimestampNTZType()

TimestampNTZType() requires Spark 3.4+. Override the built-in with a custom mapping if targeting an older cluster.

Rules without {args} discard precision — VARCHAR(255) becomes STRING.

Rules containing {args} preserve the parenthesised portion:

  • DECIMAL(10,2)DECIMAL(10,2) (Databricks)
  • DECIMAL(10,2)DecimalType(10,2) (PySpark)

Lookup is case-insensitive, and spaces or repeated separators are normalized to underscores before matching. For example, TIMESTAMP WITH TIME ZONE and TIMESTAMP_WITH_TIME_ZONE resolve to the same rule.

Conflicting mapping keys that normalize to the same canonical name are rejected when the YAML file is loaded.

Unknown types pass through unchanged — if no rule matches, datatype_converted equals the original datatype_fullname.

Mapping files are YAML with an optional header and a mappings table:

source: oracle # informational only
target: snowflake
mappings:
VARCHAR2: VARCHAR
NVARCHAR2: VARCHAR
NUMBER: "NUMBER{args}" # {args} → preserve precision: NUMBER(10,2) → NUMBER(10,2)
DATE: TIMESTAMP_NTZ
TIMESTAMP: TIMESTAMP_NTZ
TIMESTAMP_WITH_TIME_ZONE: TIMESTAMP_LTZ
CLOB: VARCHAR
BLOB: BINARY
RAW: BINARY

Use a direct path without registration:

Terminal window
katalogue dataset get <id> --include-children --datatype-converter ./mappings/oracle_snowflake.yaml

Direct .yml paths work too.

Register a mapping in katalogue.toml (or [tool.katalogue.datatype_converters] in pyproject.toml) so it can be referenced by name, just like templates:

katalogue.toml:

[datatype_converters.oracle-to-snowflake]
path = "datatype_converters/oracle_snowflake.yaml"
[datatype_converters.sqlserver-to-databricks] # override the built-in
path = "datatype_converters/my_sqlserver.yaml"

pyproject.toml:

[tool.katalogue.datatype_converters.oracle-to-snowflake]
path = "datatype_converters/oracle_snowflake.yaml"

path is resolved relative to the config file’s directory.

For each directory from cwd up to the git root:

  1. katalogue.toml — checked first
  2. pyproject.toml — used if no katalogue.toml is found in that directory

Resolution priority for --datatype-converter <value>:

  1. Repo-registered name (from the first config found above)
  2. Built-in name
  3. Direct .yaml / .yml file path

Repo-registered names always override built-ins with the same name.

datatype_converted is available in Jinja2 templates via f.datatype_converted. Use | default(...) to fall back gracefully when no mapping is active:

type: {{ f.datatype_converted | default(f.datatype_fullname | default(f.field_datatype | default('unknown', true), true), true) }}

The built-in column-mapping and dbt-source templates already use this fallback chain.