dbos 0.28.0a12__tar.gz → 0.28.0a15__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dbos-0.28.0a12 → dbos-0.28.0a15}/PKG-INFO +1 -1
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_app_db.py +14 -49
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_client.py +17 -6
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_conductor/conductor.py +32 -1
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_conductor/protocol.py +19 -2
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_dbos.py +18 -21
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_dbos_config.py +142 -114
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_sys_db.py +23 -50
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/cli/cli.py +56 -14
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/dbos-config.schema.json +0 -10
- {dbos-0.28.0a12 → dbos-0.28.0a15}/pyproject.toml +1 -1
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/conftest.py +32 -15
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_config.py +497 -452
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_docker_secrets.py +20 -185
- {dbos-0.28.0a12 → dbos-0.28.0a15}/LICENSE +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/README.md +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/__init__.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/__main__.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_admin_server.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_classproperty.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_context.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_core.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_croniter.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_debug.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_docker_pg_helper.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_error.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_event_loop.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_fastapi.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_flask.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_kafka.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_kafka_message.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_logger.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_migrations/env.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_migrations/script.py.mako +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_migrations/versions/04ca4f231047_workflow_queues_executor_id.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_migrations/versions/27ac6900c6ad_add_queue_dedup.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_migrations/versions/50f3227f0b4b_fix_job_queue.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_migrations/versions/5c361fc04708_added_system_tables.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_migrations/versions/83f3732ae8e7_workflow_timeout.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_migrations/versions/933e86bdac6a_add_queue_priority.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_migrations/versions/a3b18ad34abe_added_triggers.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_migrations/versions/d76646551a6b_job_queue_limiter.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_migrations/versions/d76646551a6c_workflow_queue.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_migrations/versions/eab0cc1d9a14_job_queue.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_migrations/versions/f4b9b32ba814_functionname_childid_op_outputs.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_outcome.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_queue.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_recovery.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_registrations.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_roles.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_scheduler.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_schemas/__init__.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_schemas/application_database.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_schemas/system_database.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_serialization.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_templates/dbos-db-starter/README.md +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_templates/dbos-db-starter/__package/__init__.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_templates/dbos-db-starter/__package/main.py.dbos +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_templates/dbos-db-starter/__package/schema.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_templates/dbos-db-starter/alembic.ini +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_templates/dbos-db-starter/dbos-config.yaml.dbos +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_templates/dbos-db-starter/migrations/env.py.dbos +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_templates/dbos-db-starter/migrations/script.py.mako +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_templates/dbos-db-starter/migrations/versions/2024_07_31_180642_init.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_templates/dbos-db-starter/start_postgres_docker.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_tracer.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_utils.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/_workflow_commands.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/cli/_github_init.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/cli/_template_init.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/dbos/py.typed +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/__init__.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/atexit_no_ctor.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/atexit_no_launch.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/classdefs.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/client_collateral.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/client_worker.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/dupname_classdefs1.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/dupname_classdefsa.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/more_classdefs.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/queuedworkflow.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_admin_server.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_async.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_classdecorators.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_client.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_concurrency.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_croniter.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_dbos.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_debug.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_failures.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_fastapi.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_fastapi_roles.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_flask.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_kafka.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_outcome.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_package.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_queue.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_scheduler.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_schema_migration.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_singleton.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_spans.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_sqlalchemy.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_workflow_introspection.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/tests/test_workflow_management.py +0 -0
- {dbos-0.28.0a12 → dbos-0.28.0a15}/version/__init__.py +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import List, Optional, TypedDict
|
1
|
+
from typing import Any, Dict, List, Optional, TypedDict
|
2
2
|
|
3
3
|
import sqlalchemy as sa
|
4
4
|
import sqlalchemy.dialects.postgresql as pg
|
@@ -7,7 +7,6 @@ from sqlalchemy.exc import DBAPIError
|
|
7
7
|
from sqlalchemy.orm import Session, sessionmaker
|
8
8
|
|
9
9
|
from . import _serialization
|
10
|
-
from ._dbos_config import DatabaseConfig
|
11
10
|
from ._error import DBOSUnexpectedStepError, DBOSWorkflowConflictIDError
|
12
11
|
from ._schemas.application_database import ApplicationSchema
|
13
12
|
from ._sys_db import StepInfo
|
@@ -31,67 +30,33 @@ class RecordedResult(TypedDict):
|
|
31
30
|
|
32
31
|
class ApplicationDatabase:
|
33
32
|
|
34
|
-
def __init__(
|
35
|
-
|
36
|
-
|
33
|
+
def __init__(
|
34
|
+
self,
|
35
|
+
*,
|
36
|
+
database_url: str,
|
37
|
+
engine_kwargs: Dict[str, Any],
|
38
|
+
debug_mode: bool = False,
|
39
|
+
):
|
40
|
+
app_db_url = sa.make_url(database_url).set(drivername="postgresql+psycopg")
|
37
41
|
|
38
42
|
# If the application database does not already exist, create it
|
39
43
|
if not debug_mode:
|
40
|
-
|
41
|
-
"
|
42
|
-
|
43
|
-
password=database["password"],
|
44
|
-
host=database["hostname"],
|
45
|
-
port=database["port"],
|
46
|
-
database="postgres",
|
44
|
+
postgres_db_engine = sa.create_engine(
|
45
|
+
app_db_url.set(database="postgres"),
|
46
|
+
**engine_kwargs,
|
47
47
|
)
|
48
|
-
postgres_db_engine = sa.create_engine(postgres_db_url)
|
49
48
|
with postgres_db_engine.connect() as conn:
|
50
49
|
conn.execution_options(isolation_level="AUTOCOMMIT")
|
51
50
|
if not conn.execute(
|
52
51
|
sa.text("SELECT 1 FROM pg_database WHERE datname=:db_name"),
|
53
|
-
parameters={"db_name":
|
52
|
+
parameters={"db_name": app_db_url.database},
|
54
53
|
).scalar():
|
55
|
-
conn.execute(sa.text(f"CREATE DATABASE {
|
54
|
+
conn.execute(sa.text(f"CREATE DATABASE {app_db_url.database}"))
|
56
55
|
postgres_db_engine.dispose()
|
57
56
|
|
58
|
-
# Create a connection pool for the application database
|
59
|
-
app_db_url = sa.URL.create(
|
60
|
-
"postgresql+psycopg",
|
61
|
-
username=database["username"],
|
62
|
-
password=database["password"],
|
63
|
-
host=database["hostname"],
|
64
|
-
port=database["port"],
|
65
|
-
database=app_db_name,
|
66
|
-
)
|
67
|
-
|
68
|
-
connect_args = {}
|
69
|
-
if (
|
70
|
-
"connectionTimeoutMillis" in database
|
71
|
-
and database["connectionTimeoutMillis"]
|
72
|
-
):
|
73
|
-
connect_args["connect_timeout"] = int(
|
74
|
-
database["connectionTimeoutMillis"] / 1000
|
75
|
-
)
|
76
|
-
|
77
|
-
pool_size = database.get("app_db_pool_size")
|
78
|
-
if pool_size is None:
|
79
|
-
pool_size = 20
|
80
|
-
|
81
|
-
engine_kwargs = database.get("db_engine_kwargs")
|
82
57
|
if engine_kwargs is None:
|
83
58
|
engine_kwargs = {}
|
84
59
|
|
85
|
-
# Respect user-provided values. Otherwise, set defaults.
|
86
|
-
if "pool_size" not in engine_kwargs:
|
87
|
-
engine_kwargs["pool_size"] = pool_size
|
88
|
-
if "max_overflow" not in engine_kwargs:
|
89
|
-
engine_kwargs["max_overflow"] = 0
|
90
|
-
if "pool_timeout" not in engine_kwargs:
|
91
|
-
engine_kwargs["pool_timeout"] = 30
|
92
|
-
if "connect_args" not in engine_kwargs:
|
93
|
-
engine_kwargs["connect_args"] = connect_args
|
94
|
-
|
95
60
|
self.engine = sa.create_engine(
|
96
61
|
app_db_url,
|
97
62
|
**engine_kwargs,
|
@@ -15,7 +15,6 @@ else:
|
|
15
15
|
|
16
16
|
from dbos import _serialization
|
17
17
|
from dbos._dbos import WorkflowHandle, WorkflowHandleAsync
|
18
|
-
from dbos._dbos_config import parse_database_url_to_dbconfig
|
19
18
|
from dbos._error import DBOSException, DBOSNonExistentWorkflowError
|
20
19
|
from dbos._registrations import DEFAULT_MAX_RECOVERY_ATTEMPTS
|
21
20
|
from dbos._serialization import WorkflowInputs
|
@@ -100,11 +99,23 @@ class WorkflowHandleClientAsyncPolling(Generic[R]):
|
|
100
99
|
|
101
100
|
class DBOSClient:
|
102
101
|
def __init__(self, database_url: str, *, system_database: Optional[str] = None):
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
102
|
+
self._sys_db = SystemDatabase(
|
103
|
+
database_url=database_url,
|
104
|
+
engine_kwargs={
|
105
|
+
"pool_timeout": 30,
|
106
|
+
"max_overflow": 0,
|
107
|
+
"pool_size": 2,
|
108
|
+
},
|
109
|
+
sys_db_name=system_database,
|
110
|
+
)
|
111
|
+
self._app_db = ApplicationDatabase(
|
112
|
+
database_url=database_url,
|
113
|
+
engine_kwargs={
|
114
|
+
"pool_timeout": 30,
|
115
|
+
"max_overflow": 0,
|
116
|
+
"pool_size": 2,
|
117
|
+
},
|
118
|
+
)
|
108
119
|
self._db_url = database_url
|
109
120
|
|
110
121
|
def destroy(self) -> None:
|
@@ -2,6 +2,7 @@ import socket
|
|
2
2
|
import threading
|
3
3
|
import time
|
4
4
|
import traceback
|
5
|
+
import uuid
|
5
6
|
from importlib.metadata import version
|
6
7
|
from typing import TYPE_CHECKING, Optional
|
7
8
|
|
@@ -9,6 +10,7 @@ from websockets import ConnectionClosed, ConnectionClosedOK, InvalidStatus
|
|
9
10
|
from websockets.sync.client import connect
|
10
11
|
from websockets.sync.connection import Connection
|
11
12
|
|
13
|
+
from dbos._context import SetWorkflowID
|
12
14
|
from dbos._utils import GlobalParams
|
13
15
|
from dbos._workflow_commands import (
|
14
16
|
get_workflow,
|
@@ -168,10 +170,11 @@ class ConductorWebsocket(threading.Thread):
|
|
168
170
|
)
|
169
171
|
websocket.send(resume_response.to_json())
|
170
172
|
elif msg_type == p.MessageType.RESTART:
|
173
|
+
# TODO: deprecate this message type in favor of Fork
|
171
174
|
restart_message = p.RestartRequest.from_json(message)
|
172
175
|
success = True
|
173
176
|
try:
|
174
|
-
self.dbos.
|
177
|
+
self.dbos.fork_workflow(restart_message.workflow_id, 1)
|
175
178
|
except Exception as e:
|
176
179
|
error_message = f"Exception encountered when restarting workflow {restart_message.workflow_id}: {traceback.format_exc()}"
|
177
180
|
self.dbos.logger.error(error_message)
|
@@ -183,6 +186,34 @@ class ConductorWebsocket(threading.Thread):
|
|
183
186
|
error_message=error_message,
|
184
187
|
)
|
185
188
|
websocket.send(restart_response.to_json())
|
189
|
+
elif msg_type == p.MessageType.FORK_WORKFLOW:
|
190
|
+
fork_message = p.ForkWorkflowRequest.from_json(message)
|
191
|
+
new_workflow_id = fork_message.body["new_workflow_id"]
|
192
|
+
if new_workflow_id is None:
|
193
|
+
new_workflow_id = str(uuid.uuid4())
|
194
|
+
workflow_id = fork_message.body["workflow_id"]
|
195
|
+
start_step = fork_message.body["start_step"]
|
196
|
+
app_version = fork_message.body["application_version"]
|
197
|
+
try:
|
198
|
+
with SetWorkflowID(new_workflow_id):
|
199
|
+
new_handle = self.dbos.fork_workflow(
|
200
|
+
workflow_id,
|
201
|
+
start_step,
|
202
|
+
application_version=app_version,
|
203
|
+
)
|
204
|
+
new_workflow_id = new_handle.workflow_id
|
205
|
+
except Exception as e:
|
206
|
+
error_message = f"Exception encountered when forking workflow {workflow_id} to new workflow {new_workflow_id} on step {start_step}, app version {app_version}: {traceback.format_exc()}"
|
207
|
+
self.dbos.logger.error(error_message)
|
208
|
+
new_workflow_id = None
|
209
|
+
|
210
|
+
fork_response = p.ForkWorkflowResponse(
|
211
|
+
type=p.MessageType.FORK_WORKFLOW,
|
212
|
+
request_id=base_message.request_id,
|
213
|
+
new_workflow_id=new_workflow_id,
|
214
|
+
error_message=error_message,
|
215
|
+
)
|
216
|
+
websocket.send(fork_response.to_json())
|
186
217
|
elif msg_type == p.MessageType.LIST_WORKFLOWS:
|
187
218
|
list_workflows_message = p.ListWorkflowsRequest.from_json(
|
188
219
|
message
|
@@ -17,6 +17,7 @@ class MessageType(str, Enum):
|
|
17
17
|
GET_WORKFLOW = "get_workflow"
|
18
18
|
EXIST_PENDING_WORKFLOWS = "exist_pending_workflows"
|
19
19
|
LIST_STEPS = "list_steps"
|
20
|
+
FORK_WORKFLOW = "fork_workflow"
|
20
21
|
|
21
22
|
|
22
23
|
T = TypeVar("T", bound="BaseMessage")
|
@@ -133,7 +134,6 @@ class WorkflowsOutput:
|
|
133
134
|
AuthenticatedRoles: Optional[str]
|
134
135
|
Input: Optional[str]
|
135
136
|
Output: Optional[str]
|
136
|
-
Request: Optional[str]
|
137
137
|
Error: Optional[str]
|
138
138
|
CreatedAt: Optional[str]
|
139
139
|
UpdatedAt: Optional[str]
|
@@ -167,7 +167,6 @@ class WorkflowsOutput:
|
|
167
167
|
AuthenticatedRoles=roles_str,
|
168
168
|
Input=inputs_str,
|
169
169
|
Output=outputs_str,
|
170
|
-
Request=request_str,
|
171
170
|
Error=error_str,
|
172
171
|
CreatedAt=created_at_str,
|
173
172
|
UpdatedAt=updated_at_str,
|
@@ -263,3 +262,21 @@ class ListStepsRequest(BaseMessage):
|
|
263
262
|
class ListStepsResponse(BaseMessage):
|
264
263
|
output: Optional[List[WorkflowSteps]]
|
265
264
|
error_message: Optional[str] = None
|
265
|
+
|
266
|
+
|
267
|
+
class ForkWorkflowBody(TypedDict):
|
268
|
+
workflow_id: str
|
269
|
+
start_step: int
|
270
|
+
application_version: Optional[str]
|
271
|
+
new_workflow_id: Optional[str]
|
272
|
+
|
273
|
+
|
274
|
+
@dataclass
|
275
|
+
class ForkWorkflowRequest(BaseMessage):
|
276
|
+
body: ForkWorkflowBody
|
277
|
+
|
278
|
+
|
279
|
+
@dataclass
|
280
|
+
class ForkWorkflowResponse(BaseMessage):
|
281
|
+
new_workflow_id: Optional[str]
|
282
|
+
error_message: Optional[str] = None
|
@@ -24,8 +24,6 @@ from typing import (
|
|
24
24
|
Tuple,
|
25
25
|
Type,
|
26
26
|
TypeVar,
|
27
|
-
Union,
|
28
|
-
cast,
|
29
27
|
)
|
30
28
|
|
31
29
|
from opentelemetry.trace import Span
|
@@ -64,7 +62,6 @@ from ._registrations import (
|
|
64
62
|
)
|
65
63
|
from ._roles import default_required_roles, required_roles
|
66
64
|
from ._scheduler import ScheduledWorkflow, scheduled
|
67
|
-
from ._schemas.system_database import SystemSchema
|
68
65
|
from ._sys_db import StepInfo, SystemDatabase, WorkflowStatus, reset_system_database
|
69
66
|
from ._tracer import DBOSTracer, dbos_tracer
|
70
67
|
|
@@ -73,7 +70,7 @@ if TYPE_CHECKING:
|
|
73
70
|
from ._kafka import _KafkaConsumerWorkflow
|
74
71
|
from flask import Flask
|
75
72
|
|
76
|
-
from sqlalchemy import
|
73
|
+
from sqlalchemy import make_url
|
77
74
|
from sqlalchemy.orm import Session
|
78
75
|
|
79
76
|
if sys.version_info < (3, 10):
|
@@ -418,11 +415,19 @@ class DBOS:
|
|
418
415
|
dbos_logger.info(f"Application version: {GlobalParams.app_version}")
|
419
416
|
self._executor_field = ThreadPoolExecutor(max_workers=64)
|
420
417
|
self._background_event_loop.start()
|
418
|
+
assert self._config["database_url"] is not None
|
419
|
+
assert self._config["database"]["sys_db_engine_kwargs"] is not None
|
421
420
|
self._sys_db_field = SystemDatabase(
|
422
|
-
self._config["
|
421
|
+
database_url=self._config["database_url"],
|
422
|
+
engine_kwargs=self._config["database"]["sys_db_engine_kwargs"],
|
423
|
+
sys_db_name=self._config["database"]["sys_db_name"],
|
424
|
+
debug_mode=debug_mode,
|
423
425
|
)
|
426
|
+
assert self._config["database"]["db_engine_kwargs"] is not None
|
424
427
|
self._app_db_field = ApplicationDatabase(
|
425
|
-
self._config["
|
428
|
+
database_url=self._config["database_url"],
|
429
|
+
engine_kwargs=self._config["database"]["db_engine_kwargs"],
|
430
|
+
debug_mode=debug_mode,
|
426
431
|
)
|
427
432
|
|
428
433
|
if debug_mode:
|
@@ -530,21 +535,13 @@ class DBOS:
|
|
530
535
|
not self._launched
|
531
536
|
), "The system database cannot be reset after DBOS is launched. Resetting the system database is a destructive operation that should only be used in a test environment."
|
532
537
|
|
533
|
-
sysdb_name =
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
"postgresql+psycopg",
|
541
|
-
username=self._config["database"]["username"],
|
542
|
-
password=self._config["database"]["password"],
|
543
|
-
host=self._config["database"]["hostname"],
|
544
|
-
port=self._config["database"]["port"],
|
545
|
-
database="postgres",
|
546
|
-
)
|
547
|
-
reset_system_database(postgres_db_url, sysdb_name)
|
538
|
+
sysdb_name = self._config["database"]["sys_db_name"]
|
539
|
+
assert sysdb_name is not None
|
540
|
+
|
541
|
+
assert self._config["database_url"] is not None
|
542
|
+
pg_db_url = make_url(self._config["database_url"]).set(database="postgres")
|
543
|
+
|
544
|
+
reset_system_database(pg_db_url, sysdb_name)
|
548
545
|
|
549
546
|
def _destroy(self) -> None:
|
550
547
|
self._initialized = False
|