mrkeyoor.com_
Tue 22 Sept 18:47 UTC
PyPIDataupdated 22 Sept 2026

sqlalchemy-utils review

SQLAlchemy-Utils 0.42.1 is a collection of add-ons for SQLAlchemy rather than another ORM. It supplies custom column types for choices, emails, URLs, phones, passwords, encryption, colors, ranges, UUIDs, locales, and search vectors; database create and inspect helpers; mapper inspection; coercion listeners; timestamp and repr mixins; aggregate attributes; generic relationships; and database views. Version 0.42.1 fixes an AttributeError in the instant-defaults listener when a column uses a Sequence default. Our Python 3.12 install imported successfully, but it took 2.09 seconds and the distribution does not publish py.typed.

Verdict

SQLAlchemy-Utils 0.42.1 installed in 0.4 seconds as 4 packages using 17 MB, imported in 2.09 seconds, and had 0 audit findings in our sandbox. Install it when several of its types and ORM helpers earn their maintenance cost; write one local SQLAlchemy helper when that is all you need.

We installed it

Lab card: what happened when we installed sqlalchemy-utilsScreenshot of sqlalchemy-utils documentation
Install✓ · 0.4s4 packages on disk · 17 MB
Importimport sqlalchemy_utils in 2.09s · pure Python · requires Python >=3.9
Known vulns0(pip-audit)

Answers from our run

Does sqlalchemy-utils install cleanly?

Yes. In a fresh container with an empty cache, pip install sqlalchemy-utils finished in 0.4s, leaving 4 packages and 17 MB on disk. pip-audit reported no known vulnerabilities.

What does sqlalchemy-utils need to run?

Python >=3.9, and nothing compiled: it is pure Python. In our run import sqlalchemy_utils succeeded in 2.09s.

sqlalchemy-utils or sqlalchemy: which should you use?

sqlalchemy: Choose built-ins plus a local TypeDecorator when only one small utility is missing. SQLAlchemy-Utils 0.42.1 installed in 0.4 seconds as 4 packages using 17 MB, imported in 2.09 seconds, and had 0 audit findings in our sandbox.

When should you not use sqlalchemy-utils?

Only 1 helper is needed. Depending on a wide ORM utility layer can cost more upgrade testing than a small local SQLAlchemy function.

API stability4/5SQLAlchemy-Utils 0.42.1 keeps long-standing type names and database, mapper, listener, aggregate, relationship, view, and mixin helpers while supporting SQLAlchemy 1.4+. The current patch fixes Sequence defaults inside instant_defaults_listener without changing its public setup call. Breadth still raises compatibility risk: these utilities touch SQLAlchemy events, type decorators, dialects, and inspection internals, and EncryptedType has already been deprecated in favor of StringEncryptedType.
Docs4/5The Read the Docs URL returned HTTP 200 and has separate material for data types, database helpers, foreign keys, ORM inspection, generic relationships, listeners, aggregates, observers, views, mixins, testing, and utility classes. Source-linked autodoc makes signatures findable. Adoption details are scattered: users must combine each type page with extras metadata, Alembic behavior, listener scope, synchronous database administration, and current SQLAlchemy 2 patterns.
Maintenance4/5PyPI published 0.42.1 on December 13, 2025 to fix Sequence defaults, and GitHub reports a push on July 8, 2026. The repository is unarchived with 1,342 stars and 227 open issues and pull requests combined. Continued fixes show active maintenance, but the queue is large for a package whose contract spans many optional projects and SQLAlchemy internals. Pinning both SQLAlchemy and SQLAlchemy-Utils remains sensible.
Ecosystem4/5The supplied snapshot records 5,836,945 weekly downloads, and GitHub reports 1,342 stars. Named extras connect the package to passlib, furl, phonenumbers, colour, cryptography, Arrow, Pendulum, Babel, intervals, and timezone libraries. This breadth lets one toolbox cover many model concerns, but the metadata contains 51 dependency entries across base and extras, and each optional package adds its own behavior and release schedule.

Use it if

  • Several models need the package's value-object types rather than one local TypeDecorator.
  • Test provisioning needs database_exists, create_database, and drop_database across supported SQL backends.
  • Mapper inspection, change detection, ordering, aggregates, generic relationships, or view helpers would remove repeated internal code.
  • The team accepts explicit optional extras and understands process-wide SQLAlchemy event listeners.
Skip it if

Setup reality

We installed SQLAlchemy-Utils 0.42.1 in a fresh Python 3.12 Bookworm sandbox. Installation took 0.4 seconds, left 4 packages, and used 17 MB. The pure-Python distribution reports 51 direct dependency entries across base and extras, requires Python 3.9 or newer, and imported in 2.09 seconds. pip-audit found 0 known vulnerabilities. The package does not ship py.typed, and its published license metadata is unknown.

The base dependency is SQLAlchemy 1.4 or newer; richer types need named extras. PasswordType needs passlib, URLType needs furl, PhoneNumberType needs phonenumbers, ColorType needs colour, encrypted strings need cryptography, and Arrow, Pendulum, Babel, intervals, and timezone helpers each add their own package. Declare the exact extras in application dependencies. Otherwise a model may import but fail when a type is constructed or return a plain value where code expected a richer object.

Automatic coercion is opt-in through force_auto_coercion and must be registered before mapper configuration. Without a mapper argument it installs listeners for every SQLAlchemy mapper in the process, which affects unrelated model sets and tests. force_instant_defaults has a similar event-driven shape; 0.42.1 specifically repairs Sequence default handling in that listener. Call setup once during application initialization, then test ordinary assignments, bulk operations, and mapper startup under the pinned SQLAlchemy version.

Custom types commonly compile to String, Unicode, Text, or binary storage, so review Alembic output and add database constraints where another writer can bypass Python validation. Password hash upgrades can occur during comparison and need a scheme policy. StringEncryptedType needs durable keys and does not make encrypted values searchable. create_database and drop_database open synchronous administrative connections; restrict them to provisioning code, verify the exact URL, and never expose drop_database on an application request path.

Patterns

Check for an existing database check-database

from sqlalchemy_utils import database_exists

if not database_exists(database_url):
    raise RuntimeError('database is missing')

The helper creates a synchronous engine and needs the target driver plus metadata access; keep credential-bearing URLs out of logs.

Provision an isolated test database create-database

from sqlalchemy_utils import create_database, database_exists

if not database_exists(test_url):
    create_database(test_url, encoding='utf8')

Administrative permission is required, and concurrent workers can race the existence check; use unique names or serialize provisioning.

Remove a disposable test database drop-database

from sqlalchemy_utils import database_exists, drop_database

assert test_url.database.startswith('test_')
if database_exists(test_url):
    drop_database(test_url)

drop_database is destructive and backend-specific. Validate the resolved database name before the call and keep it outside request code.

Map an Enum through ChoiceType store-choice

from enum import Enum
import sqlalchemy as sa
from sqlalchemy_utils import ChoiceType

class Role(Enum):
    admin = 'admin'
    member = 'member'

role = sa.Column(ChoiceType(Role, impl=sa.String(20)), nullable=False)

ChoiceType stores the Enum value through String(20); add a database CHECK or native enum when other writers must obey the same choices.

Use the package email type normalize-email

import sqlalchemy as sa
from sqlalchemy_utils import EmailType

email = sa.Column(EmailType, nullable=False, unique=True)

EmailType lowercases values but does not confirm deliverability; database collation still decides how the unique index compares text.

Expose URL values through furl coerce-url

import sqlalchemy as sa
from sqlalchemy_utils import URLType, force_auto_coercion

force_auto_coercion()
website = sa.Column(URLType)

Install sqlalchemy-utils[url] and register coercion before mappers are configured; the base package alone does not provide furl objects.

Hash and verify an assigned password hash-password

import sqlalchemy as sa
from sqlalchemy_utils import PasswordType, force_auto_coercion

force_auto_coercion()
password = sa.Column(PasswordType(schemes=['pbkdf2_sha512']), nullable=False)

user.password = plaintext
assert user.password == plaintext

Install sqlalchemy-utils[password]. Scheme choice, work factor, migration, and secret logging still belong to the application's password policy.

Register assignment coercion once enable-coercion

from sqlalchemy_utils import force_auto_coercion

force_auto_coercion()
# Import mapped models after listener registration.

With no mapper argument the listener applies to every mapper in the process, so register it during startup rather than per request.

Add ORM-managed timestamps add-timestamps

import sqlalchemy as sa
from sqlalchemy_utils import Timestamp

class Article(Timestamp, Base):
    __tablename__ = 'article'
    id = sa.Column(sa.Integer, primary_key=True)

Timestamp updates through ORM events; bulk SQL and external writers can bypass those events and need database-side timestamp policy.

Treat user wildcards as literal text escape-like

from sqlalchemy import select
from sqlalchemy_utils import escape_like

needle = escape_like(user_text)
stmt = select(User).where(User.name.ilike(f'%{needle}%', escape='*'))

Use the same escape character in the LIKE expression that escape_like expects, or the `%` and `_` characters regain wildcard meaning.

Alternatives

PackageRegistryPick it when
sqlalchemyPyPIChoose built-ins plus a local TypeDecorator when only one small utility is missing.
sqlmodelPyPIChoose it when Pydantic-style typed models should sit directly on SQLAlchemy.
sqlalchemy-mixinsPyPIChoose it when active-record CRUD, serialization, smart queries, and model mixins are the main requirement.

More data guides

numpy · fsspec · pandas · sqlalchemy · pyarrow · lxml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.