Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

invenio-db

Package Overview
Dependencies
Maintainers
1
Versions
50
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

invenio-db - npm Package Compare versions

Comparing version
2.2.1
to
2.3.0
+7
-0
CHANGES.rst

@@ -12,2 +12,9 @@ ..

Version v2.3.0 (released 2026-02-24)
- fix(config): use UTC for PostgreSQL
- feat(alembic): set lock_timeout with retry on migration connections
- docs(sphinx): ignore unresolved Flask-Alembic type refs
- tests(utc): add unit tests for UTCDateTime
Version v2.2.1 (released 2026-01-30)

@@ -14,0 +21,0 @@

+8
-1
Metadata-Version: 2.4
Name: invenio-db
Version: 2.2.1
Version: 2.3.0
Summary: Database management for Invenio.

@@ -73,2 +73,9 @@ Home-page: https://github.com/inveniosoftware/invenio-db

Version v2.3.0 (released 2026-02-24)
- fix(config): use UTC for PostgreSQL
- feat(alembic): set lock_timeout with retry on migration connections
- docs(sphinx): ignore unresolved Flask-Alembic type refs
- tests(utc): add unit tests for UTCDateTime
Version v2.2.1 (released 2026-01-30)

@@ -75,0 +82,0 @@

+1
-1

@@ -95,3 +95,3 @@ # -*- coding: utf-8 -*-

__version__ = "2.2.1"
__version__ = "2.3.0"

@@ -98,0 +98,0 @@ __all__ = (

@@ -13,3 +13,6 @@ # -*- coding: utf-8 -*-

import logging
import os
import random
import time
from importlib.metadata import PackageNotFoundError

@@ -20,4 +23,6 @@ from importlib.metadata import version as package_version

import sqlalchemy as sa
from flask import current_app
from flask_alembic import Alembic
from invenio_base.utils import entry_points
from sqlalchemy.exc import OperationalError
from sqlalchemy_utils.functions import get_class_by_table

@@ -29,3 +34,68 @@

logger = logging.getLogger(__name__)
class InvenioAlembic(Alembic):
"""Alembic with PostgreSQL lock_timeout and retry for safe migrations.
Sets lock_timeout on migration connections so DDL statements fail fast
instead of blocking reads indefinitely while waiting for exclusive locks.
On lock timeout, retries with exponential backoff. Already-applied
migrations are skipped on retry (transaction_per_migration stamps each
step).
See https://postgres.ai/blog/20210923-zero-downtime-postgres-schema-migrations-lock-timeout-and-retries
Configuration:
- ``DB_MIGRATION_LOCK_TIMEOUT``: PostgreSQL lock_timeout value
(default ``"1s"``). Set to ``"0"`` to disable.
- ``DB_MIGRATION_LOCK_TIMEOUT_RETRIES``: number of retries on lock
timeout (default ``5``).
"""
def __init__(self, *args, **kwargs):
"""Initialize InvenioAlembic."""
super().__init__(*args, **kwargs)
def _set_lock_timeout(self):
"""Set lock_timeout on all PostgreSQL migration connections."""
for ctx in self.migration_contexts.values():
if (
ctx.connection is not None
and ctx.connection.dialect.name == "postgresql"
):
timeout = current_app.config.get("DB_MIGRATION_LOCK_TIMEOUT", "1s")
ctx.connection.execute(
sa.text("SELECT set_config('lock_timeout', :val, false)"),
{"val": timeout},
)
def run_migrations(self, fn, **kwargs):
"""Run migrations with lock_timeout and retry on lock failure."""
max_retries = current_app.config.get("DB_MIGRATION_LOCK_TIMEOUT_RETRIES", 5)
for attempt in range(max_retries + 1):
self._set_lock_timeout()
try:
super().run_migrations(fn, **kwargs)
return
except OperationalError as e:
is_lock_timeout = hasattr(e.orig, "pgcode") and e.orig.pgcode == "55P03"
if not is_lock_timeout or attempt >= max_retries:
raise
# Exponential backoff with jitter
delay = min(30, 0.5 * 2**attempt) * (0.5 + random.random() * 0.5)
logger.warning(
"Migration lock timeout, retrying in %.1fs (%d/%d)",
delay,
attempt + 1,
max_retries,
)
time.sleep(delay)
# Clear cached contexts — connection is dead after the error.
# Next access to migration_contexts creates fresh connections.
self._get_cache().clear()
class InvenioDB(object):

@@ -36,3 +106,3 @@ """Invenio database extension."""

"""Extension initialization."""
self.alembic = Alembic(run_mkdir=False, command_name="alembic")
self.alembic = InvenioAlembic(run_mkdir=False, command_name="alembic")
if app:

@@ -83,2 +153,9 @@ self.init_app(app, **kwargs)

app.config.setdefault("SQLALCHEMY_TRACK_MODIFICATIONS", True)
app.config.setdefault(
"SQLALCHEMY_ENGINE_OPTIONS",
# Ensure the database is using the UTC timezone for interpreting timestamps (Postgres only).
# This overrides any default setting (e.g. in postgresql.conf). Invenio expects the DB to receive
# and provide UTC timestamps in all cases, so it's important that this doesn't get changed.
{"connect_args": {"options": "-c timezone=UTC"}},
)

@@ -85,0 +162,0 @@ # Initialize Flask-SQLAlchemy extension.

Metadata-Version: 2.4
Name: invenio-db
Version: 2.2.1
Version: 2.3.0
Summary: Database management for Invenio.

@@ -73,2 +73,9 @@ Home-page: https://github.com/inveniosoftware/invenio-db

Version v2.3.0 (released 2026-02-24)
- fix(config): use UTC for PostgreSQL
- feat(alembic): set lock_timeout with retry on migration connections
- docs(sphinx): ignore unresolved Flask-Alembic type refs
- tests(utc): add unit tests for UTCDateTime
Version v2.2.1 (released 2026-01-30)

@@ -75,0 +82,0 @@