invenio-db
Advanced tools
+14
-1
| .. | ||
| This file is part of Invenio. | ||
| Copyright (C) 2015-2024 CERN. | ||
| Copyright (C) 2024-2025 Graz University of Technology. | ||
| Copyright (C) 2024-2026 Graz University of Technology. | ||
@@ -12,2 +12,15 @@ Invenio is free software; you can redistribute it and/or modify it | ||
| Version v2.2.0 (released 2026-01-27) | ||
| - chore(black): apply changes for black>=26 | ||
| - fix: str of datetime | ||
| - change(utc): use always timezone.utc | ||
| - fix: docs reference target not found | ||
| - db: add Timestamp class | ||
| - UTCDateTime: handle more cases | ||
| - db: fix warning | ||
| - fix: docs reference target not found | ||
| - shared: add UTCDateTime column type | ||
| - chore: add nitpick_ignore to fix CI | ||
| Version v2.1.2 (released 2025-11-17) | ||
@@ -14,0 +27,0 @@ |
| Metadata-Version: 2.4 | ||
| Name: invenio-db | ||
| Version: 2.1.2 | ||
| Version: 2.2.0 | ||
| Summary: Database management for Invenio. | ||
@@ -65,3 +65,3 @@ Home-page: https://github.com/inveniosoftware/invenio-db | ||
| Copyright (C) 2015-2024 CERN. | ||
| Copyright (C) 2024-2025 Graz University of Technology. | ||
| Copyright (C) 2024-2026 Graz University of Technology. | ||
@@ -74,2 +74,15 @@ Invenio is free software; you can redistribute it and/or modify it | ||
| Version v2.2.0 (released 2026-01-27) | ||
| - chore(black): apply changes for black>=26 | ||
| - fix: str of datetime | ||
| - change(utc): use always timezone.utc | ||
| - fix: docs reference target not found | ||
| - db: add Timestamp class | ||
| - UTCDateTime: handle more cases | ||
| - db: fix warning | ||
| - fix: docs reference target not found | ||
| - shared: add UTCDateTime column type | ||
| - chore: add nitpick_ignore to fix CI | ||
| Version v2.1.2 (released 2025-11-17) | ||
@@ -76,0 +89,0 @@ |
@@ -5,3 +5,3 @@ # -*- coding: utf-8 -*- | ||
| # Copyright (C) 2015-2024 CERN. | ||
| # Copyright (C) 2024 Graz University of Technology. | ||
| # Copyright (C) 2024-2026 Graz University of Technology. | ||
| # | ||
@@ -96,3 +96,3 @@ # Invenio is free software; you can redistribute it and/or modify it | ||
| __version__ = "2.1.2" | ||
| __version__ = "2.2.0" | ||
@@ -99,0 +99,0 @@ __all__ = ( |
@@ -6,3 +6,3 @@ # -*- coding: utf-8 -*- | ||
| # Copyright (C) 2022 RERO. | ||
| # Copyright (C) 2022 Graz University of Technology. | ||
| # Copyright (C) 2022-2026 Graz University of Technology. | ||
| # | ||
@@ -9,0 +9,0 @@ # Invenio is free software; you can redistribute it and/or modify it |
| # -*- coding: utf-8 -*- | ||
| # | ||
| # This file is part of Invenio. | ||
| # Copyright (C) 2022 Graz University of Technology. | ||
| # Copyright (C) 2022-2026 Graz University of Technology. | ||
| # | ||
@@ -11,3 +11,2 @@ # Invenio is free software; you can redistribute it and/or modify it | ||
| from flask import current_app | ||
@@ -14,0 +13,0 @@ from werkzeug.local import LocalProxy |
+98
-1
@@ -5,2 +5,3 @@ # -*- coding: utf-8 -*- | ||
| # Copyright (C) 2015-2018 CERN. | ||
| # Copyright (C) 2024-2026 Graz University of Technology. | ||
| # | ||
@@ -12,6 +13,9 @@ # Invenio is free software; you can redistribute it and/or modify it | ||
| from datetime import datetime, timezone | ||
| from flask_sqlalchemy import SQLAlchemy as FlaskSQLAlchemy | ||
| from sqlalchemy import MetaData, event, util | ||
| from sqlalchemy import Column, MetaData, event, util | ||
| from sqlalchemy.engine import Engine | ||
| from sqlalchemy.sql import text | ||
| from sqlalchemy.types import DateTime, TypeDecorator | ||
| from werkzeug.local import LocalProxy | ||
@@ -34,5 +38,98 @@ | ||
| class UTCDateTime(TypeDecorator): | ||
| """Custom UTC datetime type.""" | ||
| impl = DateTime(timezone=True) | ||
| # todo: should be discussed, but has to be set explicitly to remove warning | ||
| cache_ok = False | ||
| def process_bind_param(self, value, dialect): | ||
| """Process value storing into database.""" | ||
| if value is None: | ||
| return value | ||
| if isinstance(value, str): | ||
| if " " in value: | ||
| value = value.replace(" ", "T") | ||
| value = datetime.strptime(value[0:19], "%Y-%m-%dT%H:%M:%S") | ||
| if not isinstance(value, datetime): | ||
| msg = f"ERROR: value: {value} is not of type datetime, instead of type: {type(value)}" | ||
| raise ValueError(msg) | ||
| if value.tzinfo not in (None, timezone.utc): | ||
| msg = f"Error: value: {value}, tzinfo: {value.tzinfo} doesn't have a tzinfo of None or timezone.utc." | ||
| raise ValueError(msg) | ||
| return value.replace(tzinfo=timezone.utc) | ||
| def process_result_value(self, value, dialect): | ||
| """Process value retrieving from database.""" | ||
| if value is None: | ||
| return None | ||
| if not isinstance(value, datetime): | ||
| msg = f"ERROR: value: {value} is not of type datetime." | ||
| raise ValueError(msg) | ||
| if value.tzinfo not in (None, timezone.utc): | ||
| msg = ( | ||
| f"Error: value: {value} doesn't have a tzinfo of None or timezone.utc." | ||
| ) | ||
| raise ValueError(msg) | ||
| return value.replace(tzinfo=timezone.utc) | ||
| class Timestamp: | ||
| """Adds `created` and `updated` columns to a derived declarative model. | ||
| The `created` column is handled through a default and the `updated` | ||
| column is handled through a `before_update` event that propagates | ||
| for all derived declarative models. | ||
| :: | ||
| from invenio_db import db | ||
| class SomeModel(Base, db.Timestamp): | ||
| __tablename__ = "somemodel" | ||
| id = sa.Column(sa.Integer, primary_key=True) | ||
| """ | ||
| created = Column( | ||
| UTCDateTime, | ||
| default=lambda: datetime.now(tz=timezone.utc), | ||
| nullable=False, | ||
| ) | ||
| updated = Column( | ||
| UTCDateTime, | ||
| default=lambda: datetime.now(tz=timezone.utc), | ||
| nullable=False, | ||
| ) | ||
| @event.listens_for(Timestamp, "before_update", propagate=True) | ||
| def timestamp_before_update(mapper, connection, target): | ||
| """Update timestamp on before_update event. | ||
| When a model with a timestamp is updated; force update the updated | ||
| timestamp. | ||
| """ | ||
| target.updated = datetime.now(tz=timezone.utc) | ||
| class SQLAlchemy(FlaskSQLAlchemy): | ||
| """Implement or overide extension methods.""" | ||
| def __getattr__(self, name): | ||
| """Get attr.""" | ||
| if name == "UTCDateTime": | ||
| return UTCDateTime | ||
| if name == "Timestamp": | ||
| return Timestamp | ||
| return super().__getattr__(name) | ||
| def apply_driver_hacks(self, app, sa_url, options): | ||
@@ -39,0 +136,0 @@ """Call before engine creation.""" |
+32
-1
@@ -5,3 +5,3 @@ # -*- coding: utf-8 -*- | ||
| # Copyright (C) 2017-2018 CERN. | ||
| # Copyright (C) 2022 Graz University of Technology. | ||
| # Copyright (C) 2022-2026 Graz University of Technology. | ||
| # | ||
@@ -14,2 +14,5 @@ # Invenio is free software; you can redistribute it and/or modify it | ||
| from functools import partial | ||
| from alembic import op | ||
| from flask import current_app | ||
@@ -133,1 +136,29 @@ from sqlalchemy import inspect | ||
| return engine.has_table(table) | ||
| def update_table_columns_column_type( | ||
| table_name, column_name, to_type=None, existing_type=None, existing_nullable=None | ||
| ): | ||
| """Update column type.""" | ||
| op.alter_column( | ||
| table_name, | ||
| column_name, | ||
| type_=to_type(), | ||
| existing_type=existing_type(), | ||
| existing_nullable=existing_nullable, | ||
| ) | ||
| update_table_columns_column_type_to_utc_datetime = partial( | ||
| update_table_columns_column_type, | ||
| to_type=_db.UTCDateTime, | ||
| existing_type=_db.DateTime, | ||
| existing_nullable=True, | ||
| ) | ||
| update_table_columns_column_type_to_datetime = partial( | ||
| update_table_columns_column_type, | ||
| to_type=_db.DateTime, | ||
| existing_type=_db.UTCDateTime, | ||
| existing_nullable=True, | ||
| ) |
+15
-2
| Metadata-Version: 2.4 | ||
| Name: invenio-db | ||
| Version: 2.1.2 | ||
| Version: 2.2.0 | ||
| Summary: Database management for Invenio. | ||
@@ -65,3 +65,3 @@ Home-page: https://github.com/inveniosoftware/invenio-db | ||
| Copyright (C) 2015-2024 CERN. | ||
| Copyright (C) 2024-2025 Graz University of Technology. | ||
| Copyright (C) 2024-2026 Graz University of Technology. | ||
@@ -74,2 +74,15 @@ Invenio is free software; you can redistribute it and/or modify it | ||
| Version v2.2.0 (released 2026-01-27) | ||
| - chore(black): apply changes for black>=26 | ||
| - fix: str of datetime | ||
| - change(utc): use always timezone.utc | ||
| - fix: docs reference target not found | ||
| - db: add Timestamp class | ||
| - UTCDateTime: handle more cases | ||
| - db: fix warning | ||
| - fix: docs reference target not found | ||
| - shared: add UTCDateTime column type | ||
| - chore: add nitpick_ignore to fix CI | ||
| Version v2.1.2 (released 2025-11-17) | ||
@@ -76,0 +89,0 @@ |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
71183
7.37%952
11.21%