Skip to content

BasePostgresConfig defaults use_orjson_serialization=True, so the [settings] install from the quick start fails with ImportError #59

Closed

Description

@AlexeyShalaev

Versions: sqlalchemy-foundation-kit 0.4.0 (same code on master, adcd645), SQLAlchemy 2.0.54, asyncpg 0.31.0, pydantic 2.13.5, pydantic-settings 2.15.0, Python 3.13.12; orjson not installed

BasePostgresConfig.use_orjson_serialization defaults to True (contrib/settings/postgres.py:135-138), but orjson ships only with the orjson and all extras (pyproject.toml:52-54). The quick start installs sqlalchemy-foundation-kit[settings] ("recommended", docs/guide/quickstart.md:13-14) or [settings,metrics], then builds a config with defaults and calls create_async_session_manager. That fails with ImportError before anything connects. The dishka and dependency-injector integrations call create_async_session_manager(postgres_config, ...) too (contrib/di/database.py:88, contrib/dependency_injector/database.py:40, 161), so they hit the same error. Every other entry point defaults the other way: AsyncSessionManager(use_orjson=False) (session/manager.py:235) and the builder (session/builder.py:76). Only the settings path assumes an optional dependency.

Reproduction

With pip install "sqlalchemy-foundation-kit[settings]":

from pydantic import SecretStr
from sqlalchemy_foundation_kit import create_async_session_manager
from sqlalchemy_foundation_kit.contrib.settings import BasePostgresConfig, ConnectionSettings

# pip install "sqlalchemy-foundation-kit[settings]"  -- the install the quick start recommends
config = BasePostgresConfig(
    connection=ConnectionSettings(password=SecretStr("secret"), database="app"),
    application_name="my-service",
)
print("use_orjson_serialization =", config.use_orjson_serialization)
create_async_session_manager(config)  # builds the engine, does not connect
print("manager created")

Actual

use_orjson_serialization = True
Traceback (most recent call last):
  ...
  File ".../sqlalchemy_foundation_kit/session/factories.py", line 101, in create_async_session_manager
  File ".../sqlalchemy_foundation_kit/session/manager.py", line 278, in __init__
  File ".../sqlalchemy_foundation_kit/base/engine.py", line 203, in build_engine_kwargs
  File ".../sqlalchemy_foundation_kit/base/serialization.py", line 85, in configure_orjson_serialization
  File ".../sqlalchemy_foundation_kit/base/_optional.py", line 31, in require_optional
ImportError: orjson is required for this functionality. Install it with: pip install 'sqlalchemy-foundation-kit[orjson]'

The message is clear, but anyone following the quick start hits it first, and it is about a feature that matters only to services with JSON/JSONB columns.

Why

create_async_session_manager passes use_orjson=postgres_config.use_orjson_serialization (session/factories.py:108). build_engine_kwargs then imports orjson unconditionally when the flag is set (base/engine.py:200-203).

Proposal

Default use_orjson_serialization to False, matching AsyncSessionManager and the builder. The serializer is opt-in everywhere else, and turning it on changes how JSON columns serialize (orjson's handling of datetime, non-str keys and Decimal via the kit's default encoder differs from json.dumps), so it is better as an explicit choice than as something that happens because orjson is installed. Update the defaults table (docs/guide/configuration.md:288), the docs/agents.md:311 row and the README's protocol example (README.md:149). Adding orjson to the settings extra would also fix the error, but it would tie a serialization choice to the configuration extra.

Activity

  1. AlexeyShalaev commented on Oct 16, 2026

    @AlexeyShalaev
    MemberAuthor

    Reproduced with orjson absent: ImportError from create_async_session_manager on a default BasePostgresConfig.

    Plan: default use_orjson_serialization to False, matching AsyncSessionManager and the builder, and update the defaults table, docs/agents.md and the README example. I also considered None meaning "orjson if importable". It would keep current installs unchanged, but how JSON columns serialize would then depend on whether some other package happened to pull orjson in, which is the coupling you argued against. Adding orjson to [settings] has the same problem.

    This changes behaviour for one group: services that have orjson installed, kept the default, and store values in JSON columns that only orjson serializes (datetime, UUID, Decimal, non-str keys). Their writes would start failing with TypeError from json.dumps. So the PR will be fix!: with a BREAKING CHANGE note: set use_orjson_serialization=True (env ..._USE_ORJSON_SERIALIZATION=true) to keep the old behaviour.

  2. AlexeyShalaev commented on Oct 16, 2026

    @AlexeyShalaev
    MemberAuthor

    Fixed in #66. use_orjson_serialization now defaults to False, and your script prints manager created without orjson installed.

    It's marked breaking (fix!:) because of one group of users: those with orjson installed and the default kept, writing datetime/UUID/Decimal values into JSON columns. I measured it: with json.dumps those writes fail with TypeError: Object of type datetime is not JSON serializable. If that's you, set use_orjson_serialization=True.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions