We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
bug: Static type checking (mypy) CI job failing
### Meltano Version

N/A

### Python Version

NA

### Bug scope

Other

### Operating System

N/A

### Description

Example from `main`: https://github.com/meltano/meltano/actions/runs/3129670243/jobs/5079038959

```
nox > Running session mypy
nox > Creating virtual environment (virtualenv) using python3.9 in .nox/mypy
nox > poetry build --format=wheel --no-ansi
nox > pip uninstall --yes file:///home/runner/work/meltano/meltano/dist/meltano-2.7.0-py3-none-any.whl
nox > poetry export --format=requirements.txt --dev --extras=infra --extras=mssql --extras=repl --without-hashes
The `--dev` option is deprecated, use the `--with dev` notation instead.
nox > python -m pip install --constraint=.nox/mypy/tmp/requirements.txt file:///home/runner/work/meltano/meltano/dist/meltano-2.7.0-py3-none-any.whl
nox > python -m pip install --constraint=.nox/mypy/tmp/requirements.txt mypy sqlalchemy2-stubs types-requests
nox > mypy src/meltano
src/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:39: error: Variable "f4c225a9492f_create_dedicated_job_state_table.SystemModel" is not valid as a type
src/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:39: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
src/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:39: error: Invalid base class "SystemModel"
src/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:69: error: Need type annotation for "completed_state" (hint: "completed_state: Dict[<type>, <type>] = ...")
src/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:70: error: Need type annotation for "partial_state" (hint: "partial_state: Dict[<type>, <type>] = ...")
src/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:274: error: "object" has no attribute "query"
src/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:307: error: Variable "f4c225a9492f_create_dedicated_job_state_table.SystemModel" is not valid as a type
src/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:307: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
src/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:307: error: Invalid base class "SystemModel"
src/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:340: error: Need type annotation for "completed_state" (hint: "completed_state: Dict[<type>, <type>] = ...")
src/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:341: error: Need type annotation for "partial_state" (hint: "partial_state: Dict[<type>, <type>] = ...")
src/meltano/core/job_state.py:19: error: Variable "meltano.core.models.SystemModel" is not valid as a type
src/meltano/core/job_state.py:19: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
src/meltano/core/job_state.py:19: error: Invalid base class "SystemModel"
Found 11 errors in 2 files (checked 203 source files)
nox > Command mypy src/meltano failed with exit code 1
nox > Session mypy failed.
Error: Process completed with exit code 1.
```

### Code

_No response_

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `noxfile.py`
Content:
```
1 """Nox configuration."""
2 
3 from __future__ import annotations
4 
5 import os
6 import sys
7 from pathlib import Path
8 from random import randint
9 from textwrap import dedent
10 
11 try:
12     from nox_poetry import Session
13     from nox_poetry import session as nox_session
14 except ImportError:
15     message = f"""\
16     Nox failed to import the 'nox-poetry' package.
17     Please install it using the following command:
18     {sys.executable} -m pip install nox-poetry"""
19     raise SystemExit(dedent(message)) from None
20 
21 
22 package = "meltano"
23 python_versions = ["3.10", "3.9", "3.8", "3.7"]
24 main_python_version = "3.9"
25 locations = "src", "tests", "noxfile.py"
26 
27 
28 @nox_session(python=python_versions)
29 def tests(session: Session) -> None:
30     """Execute pytest tests and compute coverage.
31 
32     Args:
33         session: Nox session.
34     """
35     backend_db = os.environ.get("PYTEST_BACKEND", "sqlite")
36 
37     if backend_db == "mssql":
38         session.install(".[mssql]")
39     else:
40         session.install(".")
41 
42     session.install(
43         "freezegun",
44         "mock",
45         "pytest",
46         "pytest-asyncio",
47         "pytest-cov",
48         "pytest-docker",
49         "pytest-order",
50         "pytest-randomly",
51         "pytest-xdist",
52         "requests-mock",
53     )
54 
55     try:
56         session.run(
57             "pytest",
58             f"--randomly-seed={randint(0, 2**32-1)}",  # noqa: S311, WPS432
59             *session.posargs,
60             env={"NOX_CURRENT_SESSION": "tests"},
61         )
62     finally:
63         if session.interactive:
64             session.notify("coverage", posargs=[])
65 
66 
67 @nox_session(python=main_python_version)
68 def coverage(session: Session) -> None:
69     """Upload coverage data.
70 
71     Args:
72         session: Nox session.
73     """
74     args = session.posargs or ["report"]
75 
76     session.install("coverage[toml]")
77 
78     if not session.posargs and any(Path().glob(".coverage.*")):
79         session.run("coverage", "combine")
80 
81     session.run("coverage", *args)
82 
83 
84 @nox_session(python=main_python_version)
85 def mypy(session: Session) -> None:
86     """Run mypy type checking.
87 
88     Args:
89         session: Nox session.
90     """
91     args = session.posargs or ["src/meltano"]
92 
93     session.install(".")
94     session.install(
95         "mypy",
96         "sqlalchemy2-stubs",
97         "types-requests",
98     )
99     session.run("mypy", *args)
100
```

Path: `src/meltano/core/job_state.py`
Content:
```
1 """Defines JobState model class."""
2 from __future__ import annotations
3 
4 from datetime import datetime
5 from typing import Any
6 
7 from sqlalchemy import Column, types
8 from sqlalchemy.ext.mutable import MutableDict
9 from sqlalchemy.orm import Session
10 
11 from meltano.core.job import JobFinder, Payload
12 from meltano.core.models import SystemModel
13 from meltano.core.sqlalchemy import JSONEncodedDict
14 from meltano.core.utils import merge
15 
16 SINGER_STATE_KEY = "singer_state"
17 
18 
19 class JobState(SystemModel):
20     """Model class that represents the current state of a given job.
21 
22     Modified during `meltano elt` or `meltano run` runs whenever a
23     STATE message is emitted by a Singer target. Also written and read
24     by `meltano state` CLI invocations. Only holds the _current_ state
25     for a given job_name. Full job run history is held by the Job model.
26     """
27 
28     __tablename__ = "state"
29     job_name = Column(types.String, unique=True, primary_key=True, nullable=False)
30 
31     updated_at = Column(types.DATETIME, onupdate=datetime.now)
32 
33     partial_state = Column(MutableDict.as_mutable(JSONEncodedDict))
34     completed_state = Column(MutableDict.as_mutable(JSONEncodedDict))
35 
36     @classmethod
37     def from_job_history(cls, session: Session, job_name: str):
38         """Build JobState from job run history.
39 
40         Args:
41             session: the session to use in finding job history
42             job_name: the name of the job to build JobState for
43 
44         Returns:
45             JobState built from job run history
46         """
47         completed_state: dict[Any, Any] = {}
48         partial_state: dict[Any, Any] = {}
49         incomplete_since = None
50         finder = JobFinder(job_name)
51 
52         # Get the state for the most recent completed job.
53         # Do not consider dummy jobs create via add_state.
54         state_job = finder.latest_with_payload(session, flags=Payload.STATE)
55         if state_job:
56             incomplete_since = state_job.ended_at
57             if SINGER_STATE_KEY in state_job.payload:
58                 merge(state_job.payload, partial_state)
59 
60         # If there have been any incomplete jobs since the most recent completed jobs,
61         # merge the state emitted by those jobs into the state for the most recent
62         # completed job. If there are no completed jobs, get the full history of
63         # incomplete jobs and use the most recent state emitted per stream
64         incomplete_state_jobs = finder.with_payload(
65             session, flags=Payload.INCOMPLETE_STATE, since=incomplete_since
66         )
67         for incomplete_state_job in incomplete_state_jobs:
68             if SINGER_STATE_KEY in incomplete_state_job.payload:
69                 partial_state = merge(incomplete_state_job.payload, partial_state)
70 
71         return cls(
72             job_name=job_name,
73             partial_state=partial_state,
74             completed_state=completed_state,
75         )
76
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/noxfile.py b/noxfile.py
--- a/noxfile.py
+++ b/noxfile.py
@@ -88,7 +88,7 @@
     Args:
         session: Nox session.
     """
-    args = session.posargs or ["src/meltano"]
+    args = session.posargs or ["src/meltano", "--exclude", "src/meltano/migrations/"]
 
     session.install(".")
     session.install(
diff --git a/src/meltano/core/job_state.py b/src/meltano/core/job_state.py
--- a/src/meltano/core/job_state.py
+++ b/src/meltano/core/job_state.py
@@ -6,7 +6,7 @@
 
 from sqlalchemy import Column, types
 from sqlalchemy.ext.mutable import MutableDict
-from sqlalchemy.orm import Session
+from sqlalchemy.orm import Mapped, Session
 
 from meltano.core.job import JobFinder, Payload
 from meltano.core.models import SystemModel
@@ -30,8 +30,8 @@
 
     updated_at = Column(types.DATETIME, onupdate=datetime.now)
 
-    partial_state = Column(MutableDict.as_mutable(JSONEncodedDict))
-    completed_state = Column(MutableDict.as_mutable(JSONEncodedDict))
+    partial_state: Mapped[Any] = Column(MutableDict.as_mutable(JSONEncodedDict))
+    completed_state: Mapped[Any] = Column(MutableDict.as_mutable(JSONEncodedDict))
 
     @classmethod
     def from_job_history(cls, session: Session, job_name: str):

{"golden_diff": "diff --git a/noxfile.py b/noxfile.py\n--- a/noxfile.py\n+++ b/noxfile.py\n@@ -88,7 +88,7 @@\n     Args:\n         session: Nox session.\n     \"\"\"\n-    args = session.posargs or [\"src/meltano\"]\n+    args = session.posargs or [\"src/meltano\", \"--exclude\", \"src/meltano/migrations/\"]\n \n     session.install(\".\")\n     session.install(\ndiff --git a/src/meltano/core/job_state.py b/src/meltano/core/job_state.py\n--- a/src/meltano/core/job_state.py\n+++ b/src/meltano/core/job_state.py\n@@ -6,7 +6,7 @@\n \n from sqlalchemy import Column, types\n from sqlalchemy.ext.mutable import MutableDict\n-from sqlalchemy.orm import Session\n+from sqlalchemy.orm import Mapped, Session\n \n from meltano.core.job import JobFinder, Payload\n from meltano.core.models import SystemModel\n@@ -30,8 +30,8 @@\n \n     updated_at = Column(types.DATETIME, onupdate=datetime.now)\n \n-    partial_state = Column(MutableDict.as_mutable(JSONEncodedDict))\n-    completed_state = Column(MutableDict.as_mutable(JSONEncodedDict))\n+    partial_state: Mapped[Any] = Column(MutableDict.as_mutable(JSONEncodedDict))\n+    completed_state: Mapped[Any] = Column(MutableDict.as_mutable(JSONEncodedDict))\n \n     @classmethod\n     def from_job_history(cls, session: Session, job_name: str):\n", "issue": "bug: Static type checking (mypy) CI job failing\n### Meltano Version\n\nN/A\n\n### Python Version\n\nNA\n\n### Bug scope\n\nOther\n\n### Operating System\n\nN/A\n\n### Description\n\nExample from `main`: https://github.com/meltano/meltano/actions/runs/3129670243/jobs/5079038959\r\n\r\n```\r\nnox > Running session mypy\r\nnox > Creating virtual environment (virtualenv) using python3.9 in .nox/mypy\r\nnox > poetry build --format=wheel --no-ansi\r\nnox > pip uninstall --yes file:///home/runner/work/meltano/meltano/dist/meltano-2.7.0-py3-none-any.whl\r\nnox > poetry export --format=requirements.txt --dev --extras=infra --extras=mssql --extras=repl --without-hashes\r\nThe `--dev` option is deprecated, use the `--with dev` notation instead.\r\nnox > python -m pip install --constraint=.nox/mypy/tmp/requirements.txt file:///home/runner/work/meltano/meltano/dist/meltano-2.7.0-py3-none-any.whl\r\nnox > python -m pip install --constraint=.nox/mypy/tmp/requirements.txt mypy sqlalchemy2-stubs types-requests\r\nnox > mypy src/meltano\r\nsrc/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:39: error: Variable \"f4c225a9492f_create_dedicated_job_state_table.SystemModel\" is not valid as a type\r\nsrc/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:39: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases\r\nsrc/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:39: error: Invalid base class \"SystemModel\"\r\nsrc/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:69: error: Need type annotation for \"completed_state\" (hint: \"completed_state: Dict[<type>, <type>] = ...\")\r\nsrc/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:70: error: Need type annotation for \"partial_state\" (hint: \"partial_state: Dict[<type>, <type>] = ...\")\r\nsrc/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:274: error: \"object\" has no attribute \"query\"\r\nsrc/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:307: error: Variable \"f4c225a9492f_create_dedicated_job_state_table.SystemModel\" is not valid as a type\r\nsrc/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:307: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases\r\nsrc/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:307: error: Invalid base class \"SystemModel\"\r\nsrc/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:340: error: Need type annotation for \"completed_state\" (hint: \"completed_state: Dict[<type>, <type>] = ...\")\r\nsrc/meltano/migrations/versions/f4c225a9492f_create_dedicated_job_state_table.py:341: error: Need type annotation for \"partial_state\" (hint: \"partial_state: Dict[<type>, <type>] = ...\")\r\nsrc/meltano/core/job_state.py:19: error: Variable \"meltano.core.models.SystemModel\" is not valid as a type\r\nsrc/meltano/core/job_state.py:19: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases\r\nsrc/meltano/core/job_state.py:19: error: Invalid base class \"SystemModel\"\r\nFound 11 errors in 2 files (checked 203 source files)\r\nnox > Command mypy src/meltano failed with exit code 1\r\nnox > Session mypy failed.\r\nError: Process completed with exit code 1.\r\n```\n\n### Code\n\n_No response_\n", "before_files": [{"content": "\"\"\"Nox configuration.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport sys\nfrom pathlib import Path\nfrom random import randint\nfrom textwrap import dedent\n\ntry:\n    from nox_poetry import Session\n    from nox_poetry import session as nox_session\nexcept ImportError:\n    message = f\"\"\"\\\n    Nox failed to import the 'nox-poetry' package.\n    Please install it using the following command:\n    {sys.executable} -m pip install nox-poetry\"\"\"\n    raise SystemExit(dedent(message)) from None\n\n\npackage = \"meltano\"\npython_versions = [\"3.10\", \"3.9\", \"3.8\", \"3.7\"]\nmain_python_version = \"3.9\"\nlocations = \"src\", \"tests\", \"noxfile.py\"\n\n\n@nox_session(python=python_versions)\ndef tests(session: Session) -> None:\n    \"\"\"Execute pytest tests and compute coverage.\n\n    Args:\n        session: Nox session.\n    \"\"\"\n    backend_db = os.environ.get(\"PYTEST_BACKEND\", \"sqlite\")\n\n    if backend_db == \"mssql\":\n        session.install(\".[mssql]\")\n    else:\n        session.install(\".\")\n\n    session.install(\n        \"freezegun\",\n        \"mock\",\n        \"pytest\",\n        \"pytest-asyncio\",\n        \"pytest-cov\",\n        \"pytest-docker\",\n        \"pytest-order\",\n        \"pytest-randomly\",\n        \"pytest-xdist\",\n        \"requests-mock\",\n    )\n\n    try:\n        session.run(\n            \"pytest\",\n            f\"--randomly-seed={randint(0, 2**32-1)}\",  # noqa: S311, WPS432\n            *session.posargs,\n            env={\"NOX_CURRENT_SESSION\": \"tests\"},\n        )\n    finally:\n        if session.interactive:\n            session.notify(\"coverage\", posargs=[])\n\n\n@nox_session(python=main_python_version)\ndef coverage(session: Session) -> None:\n    \"\"\"Upload coverage data.\n\n    Args:\n        session: Nox session.\n    \"\"\"\n    args = session.posargs or [\"report\"]\n\n    session.install(\"coverage[toml]\")\n\n    if not session.posargs and any(Path().glob(\".coverage.*\")):\n        session.run(\"coverage\", \"combine\")\n\n    session.run(\"coverage\", *args)\n\n\n@nox_session(python=main_python_version)\ndef mypy(session: Session) -> None:\n    \"\"\"Run mypy type checking.\n\n    Args:\n        session: Nox session.\n    \"\"\"\n    args = session.posargs or [\"src/meltano\"]\n\n    session.install(\".\")\n    session.install(\n        \"mypy\",\n        \"sqlalchemy2-stubs\",\n        \"types-requests\",\n    )\n    session.run(\"mypy\", *args)\n", "path": "noxfile.py"}, {"content": "\"\"\"Defines JobState model class.\"\"\"\nfrom __future__ import annotations\n\nfrom datetime import datetime\nfrom typing import Any\n\nfrom sqlalchemy import Column, types\nfrom sqlalchemy.ext.mutable import MutableDict\nfrom sqlalchemy.orm import Session\n\nfrom meltano.core.job import JobFinder, Payload\nfrom meltano.core.models import SystemModel\nfrom meltano.core.sqlalchemy import JSONEncodedDict\nfrom meltano.core.utils import merge\n\nSINGER_STATE_KEY = \"singer_state\"\n\n\nclass JobState(SystemModel):\n    \"\"\"Model class that represents the current state of a given job.\n\n    Modified during `meltano elt` or `meltano run` runs whenever a\n    STATE message is emitted by a Singer target. Also written and read\n    by `meltano state` CLI invocations. Only holds the _current_ state\n    for a given job_name. Full job run history is held by the Job model.\n    \"\"\"\n\n    __tablename__ = \"state\"\n    job_name = Column(types.String, unique=True, primary_key=True, nullable=False)\n\n    updated_at = Column(types.DATETIME, onupdate=datetime.now)\n\n    partial_state = Column(MutableDict.as_mutable(JSONEncodedDict))\n    completed_state = Column(MutableDict.as_mutable(JSONEncodedDict))\n\n    @classmethod\n    def from_job_history(cls, session: Session, job_name: str):\n        \"\"\"Build JobState from job run history.\n\n        Args:\n            session: the session to use in finding job history\n            job_name: the name of the job to build JobState for\n\n        Returns:\n            JobState built from job run history\n        \"\"\"\n        completed_state: dict[Any, Any] = {}\n        partial_state: dict[Any, Any] = {}\n        incomplete_since = None\n        finder = JobFinder(job_name)\n\n        # Get the state for the most recent completed job.\n        # Do not consider dummy jobs create via add_state.\n        state_job = finder.latest_with_payload(session, flags=Payload.STATE)\n        if state_job:\n            incomplete_since = state_job.ended_at\n            if SINGER_STATE_KEY in state_job.payload:\n                merge(state_job.payload, partial_state)\n\n        # If there have been any incomplete jobs since the most recent completed jobs,\n        # merge the state emitted by those jobs into the state for the most recent\n        # completed job. If there are no completed jobs, get the full history of\n        # incomplete jobs and use the most recent state emitted per stream\n        incomplete_state_jobs = finder.with_payload(\n            session, flags=Payload.INCOMPLETE_STATE, since=incomplete_since\n        )\n        for incomplete_state_job in incomplete_state_jobs:\n            if SINGER_STATE_KEY in incomplete_state_job.payload:\n                partial_state = merge(incomplete_state_job.payload, partial_state)\n\n        return cls(\n            job_name=job_name,\n            partial_state=partial_state,\n            completed_state=completed_state,\n        )\n", "path": "src/meltano/core/job_state.py"}], "after_files": [{"content": "\"\"\"Nox configuration.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport sys\nfrom pathlib import Path\nfrom random import randint\nfrom textwrap import dedent\n\ntry:\n    from nox_poetry import Session\n    from nox_poetry import session as nox_session\nexcept ImportError:\n    message = f\"\"\"\\\n    Nox failed to import the 'nox-poetry' package.\n    Please install it using the following command:\n    {sys.executable} -m pip install nox-poetry\"\"\"\n    raise SystemExit(dedent(message)) from None\n\n\npackage = \"meltano\"\npython_versions = [\"3.10\", \"3.9\", \"3.8\", \"3.7\"]\nmain_python_version = \"3.9\"\nlocations = \"src\", \"tests\", \"noxfile.py\"\n\n\n@nox_session(python=python_versions)\ndef tests(session: Session) -> None:\n    \"\"\"Execute pytest tests and compute coverage.\n\n    Args:\n        session: Nox session.\n    \"\"\"\n    backend_db = os.environ.get(\"PYTEST_BACKEND\", \"sqlite\")\n\n    if backend_db == \"mssql\":\n        session.install(\".[mssql]\")\n    else:\n        session.install(\".\")\n\n    session.install(\n        \"freezegun\",\n        \"mock\",\n        \"pytest\",\n        \"pytest-asyncio\",\n        \"pytest-cov\",\n        \"pytest-docker\",\n        \"pytest-order\",\n        \"pytest-randomly\",\n        \"pytest-xdist\",\n        \"requests-mock\",\n    )\n\n    try:\n        session.run(\n            \"pytest\",\n            f\"--randomly-seed={randint(0, 2**32-1)}\",  # noqa: S311, WPS432\n            *session.posargs,\n            env={\"NOX_CURRENT_SESSION\": \"tests\"},\n        )\n    finally:\n        if session.interactive:\n            session.notify(\"coverage\", posargs=[])\n\n\n@nox_session(python=main_python_version)\ndef coverage(session: Session) -> None:\n    \"\"\"Upload coverage data.\n\n    Args:\n        session: Nox session.\n    \"\"\"\n    args = session.posargs or [\"report\"]\n\n    session.install(\"coverage[toml]\")\n\n    if not session.posargs and any(Path().glob(\".coverage.*\")):\n        session.run(\"coverage\", \"combine\")\n\n    session.run(\"coverage\", *args)\n\n\n@nox_session(python=main_python_version)\ndef mypy(session: Session) -> None:\n    \"\"\"Run mypy type checking.\n\n    Args:\n        session: Nox session.\n    \"\"\"\n    args = session.posargs or [\"src/meltano\", \"--exclude\", \"src/meltano/migrations/\"]\n\n    session.install(\".\")\n    session.install(\n        \"mypy\",\n        \"sqlalchemy2-stubs\",\n        \"types-requests\",\n    )\n    session.run(\"mypy\", *args)\n", "path": "noxfile.py"}, {"content": "\"\"\"Defines JobState model class.\"\"\"\nfrom __future__ import annotations\n\nfrom datetime import datetime\nfrom typing import Any\n\nfrom sqlalchemy import Column, types\nfrom sqlalchemy.ext.mutable import MutableDict\nfrom sqlalchemy.orm import Mapped, Session\n\nfrom meltano.core.job import JobFinder, Payload\nfrom meltano.core.models import SystemModel\nfrom meltano.core.sqlalchemy import JSONEncodedDict\nfrom meltano.core.utils import merge\n\nSINGER_STATE_KEY = \"singer_state\"\n\n\nclass JobState(SystemModel):\n    \"\"\"Model class that represents the current state of a given job.\n\n    Modified during `meltano elt` or `meltano run` runs whenever a\n    STATE message is emitted by a Singer target. Also written and read\n    by `meltano state` CLI invocations. Only holds the _current_ state\n    for a given job_name. Full job run history is held by the Job model.\n    \"\"\"\n\n    __tablename__ = \"state\"\n    job_name = Column(types.String, unique=True, primary_key=True, nullable=False)\n\n    updated_at = Column(types.DATETIME, onupdate=datetime.now)\n\n    partial_state: Mapped[Any] = Column(MutableDict.as_mutable(JSONEncodedDict))\n    completed_state: Mapped[Any] = Column(MutableDict.as_mutable(JSONEncodedDict))\n\n    @classmethod\n    def from_job_history(cls, session: Session, job_name: str):\n        \"\"\"Build JobState from job run history.\n\n        Args:\n            session: the session to use in finding job history\n            job_name: the name of the job to build JobState for\n\n        Returns:\n            JobState built from job run history\n        \"\"\"\n        completed_state: dict[Any, Any] = {}\n        partial_state: dict[Any, Any] = {}\n        incomplete_since = None\n        finder = JobFinder(job_name)\n\n        # Get the state for the most recent completed job.\n        # Do not consider dummy jobs create via add_state.\n        state_job = finder.latest_with_payload(session, flags=Payload.STATE)\n        if state_job:\n            incomplete_since = state_job.ended_at\n            if SINGER_STATE_KEY in state_job.payload:\n                merge(state_job.payload, partial_state)\n\n        # If there have been any incomplete jobs since the most recent completed jobs,\n        # merge the state emitted by those jobs into the state for the most recent\n        # completed job. If there are no completed jobs, get the full history of\n        # incomplete jobs and use the most recent state emitted per stream\n        incomplete_state_jobs = finder.with_payload(\n            session, flags=Payload.INCOMPLETE_STATE, since=incomplete_since\n        )\n        for incomplete_state_job in incomplete_state_jobs:\n            if SINGER_STATE_KEY in incomplete_state_job.payload:\n                partial_state = merge(incomplete_state_job.payload, partial_state)\n\n        return cls(\n            job_name=job_name,\n            partial_state=partial_state,\n            completed_state=completed_state,\n        )\n", "path": "src/meltano/core/job_state.py"}]}