From 12e68aa835a437e21d49d5bb00cef731e1bde648 Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Mon, 1 Jan 2024 12:38:10 +0100 Subject: [PATCH 1/2] Require sqlalchemy>=2 and upgrade code. --- .pre-commit-config.yaml | 2 +- docs/source/changes.md | 1 + environment.yml | 2 +- pyproject.toml | 2 +- src/_pytask/database_utils.py | 20 +++++++++++--------- src/_pytask/profile.py | 14 +++++++------- 6 files changed, 22 insertions(+), 19 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 629b0d5c..4dd79630 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -65,7 +65,7 @@ repos: optree, pluggy, rich, - sqlalchemy, + sqlalchemy>2, types-setuptools, ] pass_filenames: false diff --git a/docs/source/changes.md b/docs/source/changes.md index 9bd779ef..8d1b172d 100644 --- a/docs/source/changes.md +++ b/docs/source/changes.md @@ -31,6 +31,7 @@ releases are available on [PyPI](https://pypi.org/project/pytask) and the signatures suggested. - {pull}`542` refactors the plugin manager. - {pull}`543` fixes imports in tests and related issues. +- {pull}`544` requires sqlalchemy `>=2` and upgrade syntax. ## 0.4.4 - 2023-12-04 diff --git a/environment.yml b/environment.yml index 35943e32..7074be72 100644 --- a/environment.yml +++ b/environment.yml @@ -18,7 +18,7 @@ dependencies: - pluggy >=1.0.0 - optree >=0.9 - rich - - sqlalchemy >=1.4.36 + - sqlalchemy >=2 - tomli >=1.0.0 - typing_extensions - universal_pathlib diff --git a/pyproject.toml b/pyproject.toml index 987b39fe..4a42ab3d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ dependencies = [ "packaging", "pluggy>=1", "rich", - "sqlalchemy>=1.4.36", + "sqlalchemy>=2", 'tomli>=1; python_version < "3.11"', 'typing-extensions; python_version < "3.9"', ] diff --git a/src/_pytask/database_utils.py b/src/_pytask/database_utils.py index 95a22344..46e3437c 100644 --- a/src/_pytask/database_utils.py +++ b/src/_pytask/database_utils.py @@ -4,11 +4,12 @@ from typing import TYPE_CHECKING from _pytask.dag_utils import node_and_neighbors -from sqlalchemy import Column from sqlalchemy import create_engine -from sqlalchemy import String -from sqlalchemy.orm import declarative_base +from sqlalchemy.orm import DeclarativeBase +from sqlalchemy.orm import Mapped +from sqlalchemy.orm import mapped_column from sqlalchemy.orm import sessionmaker +from typing_extensions import Annotated if TYPE_CHECKING: from _pytask.node_protocols import PNode @@ -27,17 +28,18 @@ DatabaseSession = sessionmaker() -BaseTable = declarative_base() +class BaseTable(DeclarativeBase): + pass -class State(BaseTable): # type: ignore[valid-type, misc] +class State(BaseTable): """Represent the state of a node in relation to a task.""" __tablename__ = "state" - task = Column(String, primary_key=True) - node = Column(String, primary_key=True) - hash_ = Column(String) + task: Mapped[Annotated[str, mapped_column(primary_key=True)]] + node: Mapped[Annotated[str, mapped_column(primary_key=True)]] + hash_: Mapped[str] def create_database(url: str) -> None: @@ -54,7 +56,7 @@ def _create_or_update_state(first_key: str, second_key: str, hash_: str) -> None if not state_in_db: session.add(State(task=first_key, node=second_key, hash_=hash_)) else: - state_in_db.hash_ = hash_ # type: ignore[assignment] + state_in_db.hash_ = hash_ session.commit() diff --git a/src/_pytask/profile.py b/src/_pytask/profile.py index 3147042a..7544a54a 100644 --- a/src/_pytask/profile.py +++ b/src/_pytask/profile.py @@ -29,12 +29,12 @@ from _pytask.session import Session from _pytask.traceback import Traceback from rich.table import Table -from sqlalchemy import Column -from sqlalchemy import Float -from sqlalchemy import String +from typing_extensions import Annotated if TYPE_CHECKING: + from sqlalchemy.orm import mapped_column + from sqlalchemy.orm import Mapped from _pytask.reports import ExecutionReport from pathlib import Path from typing import NoReturn @@ -51,9 +51,9 @@ class Runtime(BaseTable): __tablename__ = "runtime" - task = Column(String, primary_key=True) - date = Column(Float) - duration = Column(Float) + task: Mapped[Annotated[str, mapped_column(primary_key=True)]] + date: Mapped[float] + duration: Mapped[float] @hookimpl(tryfirst=True) @@ -198,7 +198,7 @@ def _collect_runtimes(tasks: list[PTask]) -> dict[str, float]: """Collect runtimes.""" with DatabaseSession() as session: runtimes = [session.get(Runtime, task.signature) for task in tasks] - return {task.name: r.duration for task, r in zip(tasks, runtimes) if r} # type: ignore[misc] + return {task.name: r.duration for task, r in zip(tasks, runtimes) if r} class FileSizeNameSpace: From 320a09627ed191af944665c6588e67136fb6b2ca Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Mon, 1 Jan 2024 21:09:03 +0100 Subject: [PATCH 2/2] Fix. --- docs/source/changes.md | 7 +++++-- src/_pytask/database_utils.py | 5 ++--- src/_pytask/profile.py | 8 +++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/source/changes.md b/docs/source/changes.md index 8d1b172d..b03b8898 100644 --- a/docs/source/changes.md +++ b/docs/source/changes.md @@ -5,7 +5,11 @@ chronological order. Releases follow [semantic versioning](https://semver.org/) releases are available on [PyPI](https://pypi.org/project/pytask) and [Anaconda.org](https://anaconda.org/conda-forge/pytask). -## 0.4.5 - 2023-12-xx +## 0.5.0 - 2024-xx-xx + +- {pull}`544` requires sqlalchemy `>=2` and upgrades the syntax. + +## 0.4.5 - 2024-01-xx - {pull}`515` enables tests with graphviz in CI. Thanks to {user}`NickCrews`. - {pull}`517` raises an error when the configuration file contains a non-existing path @@ -31,7 +35,6 @@ releases are available on [PyPI](https://pypi.org/project/pytask) and the signatures suggested. - {pull}`542` refactors the plugin manager. - {pull}`543` fixes imports in tests and related issues. -- {pull}`544` requires sqlalchemy `>=2` and upgrade syntax. ## 0.4.4 - 2023-12-04 diff --git a/src/_pytask/database_utils.py b/src/_pytask/database_utils.py index 46e3437c..1e26b9f8 100644 --- a/src/_pytask/database_utils.py +++ b/src/_pytask/database_utils.py @@ -9,7 +9,6 @@ from sqlalchemy.orm import Mapped from sqlalchemy.orm import mapped_column from sqlalchemy.orm import sessionmaker -from typing_extensions import Annotated if TYPE_CHECKING: from _pytask.node_protocols import PNode @@ -37,8 +36,8 @@ class State(BaseTable): __tablename__ = "state" - task: Mapped[Annotated[str, mapped_column(primary_key=True)]] - node: Mapped[Annotated[str, mapped_column(primary_key=True)]] + task: Mapped[str] = mapped_column(primary_key=True) + node: Mapped[str] = mapped_column(primary_key=True) hash_: Mapped[str] diff --git a/src/_pytask/profile.py b/src/_pytask/profile.py index 7544a54a..9d9ba119 100644 --- a/src/_pytask/profile.py +++ b/src/_pytask/profile.py @@ -29,12 +29,10 @@ from _pytask.session import Session from _pytask.traceback import Traceback from rich.table import Table -from typing_extensions import Annotated - +from sqlalchemy.orm import Mapped +from sqlalchemy.orm import mapped_column if TYPE_CHECKING: - from sqlalchemy.orm import mapped_column - from sqlalchemy.orm import Mapped from _pytask.reports import ExecutionReport from pathlib import Path from typing import NoReturn @@ -51,7 +49,7 @@ class Runtime(BaseTable): __tablename__ = "runtime" - task: Mapped[Annotated[str, mapped_column(primary_key=True)]] + task: Mapped[str] = mapped_column(primary_key=True) date: Mapped[float] duration: Mapped[float]