Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]

steps:
- uses: actions/checkout@v4
Expand Down
14 changes: 7 additions & 7 deletions docs/configuring.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,16 @@ table, or a child table.
### Data types

By default, the data type defined in the database table for each column is based on a mapping between the data type
indicated in the XSD and a corresponding `sqlalchemy` type implemented in the following three functions:
indicated in the XSD and a corresponding `sqlalchemy` type implemented in the following three methods:

??? info "Default: `types_mapping_default`"
::: xml2db.table.column.types_mapping_default
??? info "Default: `DatabaseDialect.column_type`"
::: xml2db.dialect.base.DatabaseDialect.column_type

??? info "MySQL: `types_mapping_mysql`"
::: xml2db.table.column.types_mapping_mysql
??? info "MySQL: `MySQLDialect.column_type`"
::: xml2db.dialect.mysql.MySQLDialect.column_type

??? info "MSSQL: `types_mapping_mssql`"
::: xml2db.table.column.types_mapping_mssql
??? info "MSSQL: `MSSQLDialect.column_type`"
::: xml2db.dialect.mssql.MSSQLDialect.column_type

You may override this mapping by specifying a column type for any field in the model config. Custom column types are
defined as `sqlalchemy` types and will be passed to the `sqlalchemy.Column` constructor as is.
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"

[project]
name = "xml2db"
version = "0.12.6"
version = "0.13.0"
authors = [
{ name="Commission de régulation de l'énergie", email="opensource@cre.fr" },
]
description = "Import complex XML files to a relational database"
readme = "README.md"
requires-python = ">=3.9"
requires-python = ">=3.10"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
Expand Down
65 changes: 65 additions & 0 deletions src/xml2db/dialect/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"""Backend-specific dialect classes for xml2db.

This package centralises all database-backend-specific behaviour that was
previously scattered across the codebase as ``if db_type == "..."``
conditionals. Each supported backend has a dedicated subclass of
:class:`~xml2db.dialect.base.DatabaseDialect`. Unknown backends fall back to
the base class, which provides safe, generic defaults.

Usage::

from xml2db.dialect import get_dialect

dialect = get_dialect("postgresql")
physical_name = dialect.db_identifier("some_very_long_xsd_derived_name")

The registry is a plain dict so that third-party code (or tests) can register
custom dialects without subclassing anything in xml2db::

from xml2db.dialect import DIALECT_REGISTRY
from mypackage import OracleDialect

DIALECT_REGISTRY["oracle"] = OracleDialect
"""

from .base import DatabaseDialect
from .duckdb import DuckDBDialect
from .mssql import MSSQLDialect
from .mysql import MySQLDialect
from .postgresql import PostgreSQLDialect

__all__ = [
"DatabaseDialect",
"DuckDBDialect",
"MSSQLDialect",
"MySQLDialect",
"PostgreSQLDialect",
"DIALECT_REGISTRY",
"get_dialect",
]

# Maps the SQLAlchemy dialect name (as returned by engine.dialect.name) to
# the corresponding DatabaseDialect subclass.
DIALECT_REGISTRY: dict[str, type[DatabaseDialect]] = {
"postgresql": PostgreSQLDialect,
"mssql": MSSQLDialect,
"mysql": MySQLDialect,
"mariadb": MySQLDialect, # SQLAlchemy reports MariaDB as "mariadb"
"duckdb": DuckDBDialect,
}


def get_dialect(db_type: str | None) -> DatabaseDialect:
"""Return a :class:`DatabaseDialect` instance for the given backend name.

Args:
db_type: The SQLAlchemy dialect name, e.g. ``"postgresql"``,
``"mssql"``, ``"mysql"``, ``"duckdb"``. ``None`` or any
unrecognised string falls back to the base
:class:`DatabaseDialect`, which uses safe generic defaults.

Returns:
An instantiated :class:`DatabaseDialect` (or subclass) ready for use.
"""
cls = DIALECT_REGISTRY.get(db_type, DatabaseDialect)
return cls()
Loading
Loading