dbos 0.13.0a2__tar.gz → 0.14.0a5__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.
Potentially problematic release.
This version of dbos might be problematic. Click here for more details.
- {dbos-0.13.0a2 → dbos-0.14.0a5}/PKG-INFO +1 -1
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_dbos.py +16 -8
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_dbos_config.py +2 -2
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_sys_db.py +7 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/cli.py +76 -5
- {dbos-0.13.0a2 → dbos-0.14.0a5}/pyproject.toml +1 -1
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/test_config.py +3 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/test_failures.py +43 -2
- {dbos-0.13.0a2 → dbos-0.14.0a5}/LICENSE +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/README.md +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/__init__.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_admin_sever.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_app_db.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_classproperty.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_context.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_core.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_croniter.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_error.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_fastapi.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_flask.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_kafka.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_kafka_message.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_logger.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_migrations/env.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_migrations/script.py.mako +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_migrations/versions/50f3227f0b4b_fix_job_queue.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_migrations/versions/5c361fc04708_added_system_tables.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_migrations/versions/a3b18ad34abe_added_triggers.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_migrations/versions/d76646551a6b_job_queue_limiter.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_migrations/versions/d76646551a6c_workflow_queue.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_migrations/versions/eab0cc1d9a14_job_queue.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_queue.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_recovery.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_registrations.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_request.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_roles.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_scheduler.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_schemas/__init__.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_schemas/application_database.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_schemas/system_database.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_serialization.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_templates/hello/README.md +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_templates/hello/__package/__init__.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_templates/hello/__package/main.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_templates/hello/__package/schema.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_templates/hello/alembic.ini +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_templates/hello/dbos-config.yaml.dbos +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_templates/hello/migrations/env.py.dbos +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_templates/hello/migrations/script.py.mako +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_templates/hello/migrations/versions/2024_07_31_180642_init.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_templates/hello/start_postgres_docker.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_tracer.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/dbos-config.schema.json +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/py.typed +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/__init__.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/atexit_no_ctor.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/atexit_no_launch.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/classdefs.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/conftest.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/more_classdefs.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/test_admin_server.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/test_classdecorators.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/test_concurrency.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/test_croniter.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/test_dbos.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/test_fastapi.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/test_fastapi_roles.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/test_flask.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/test_kafka.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/test_package.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/test_queue.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/test_scheduler.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/test_schema_migration.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/tests/test_singleton.py +0 -0
- {dbos-0.13.0a2 → dbos-0.14.0a5}/version/__init__.py +0 -0
|
@@ -619,16 +619,24 @@ class DBOS:
|
|
|
619
619
|
It is important to use `DBOS.sleep` (as opposed to any other sleep) within workflows,
|
|
620
620
|
as the `DBOS.sleep`s are durable and completed sleeps will be skipped during recovery.
|
|
621
621
|
"""
|
|
622
|
-
|
|
623
|
-
attributes: TracedAttributes = {
|
|
624
|
-
"name": "sleep",
|
|
625
|
-
}
|
|
626
622
|
if seconds <= 0:
|
|
627
623
|
return
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
624
|
+
cur_ctx = get_local_dbos_context()
|
|
625
|
+
if cur_ctx is not None:
|
|
626
|
+
# Must call it within a workflow
|
|
627
|
+
assert (
|
|
628
|
+
cur_ctx.is_workflow()
|
|
629
|
+
), "sleep() must be called from within a workflow"
|
|
630
|
+
attributes: TracedAttributes = {
|
|
631
|
+
"name": "sleep",
|
|
632
|
+
}
|
|
633
|
+
with EnterDBOSStep(attributes) as ctx:
|
|
634
|
+
_get_dbos_instance()._sys_db.sleep(
|
|
635
|
+
ctx.workflow_id, ctx.curr_step_function_id, seconds
|
|
636
|
+
)
|
|
637
|
+
else:
|
|
638
|
+
# Cannot call it from outside of a workflow
|
|
639
|
+
raise DBOSException("sleep() must be called from within a workflow")
|
|
632
640
|
|
|
633
641
|
@classmethod
|
|
634
642
|
def set_event(cls, key: str, value: Any) -> None:
|
|
@@ -169,7 +169,7 @@ def load_config(config_file_path: str = "dbos-config.yaml") -> ConfigFile:
|
|
|
169
169
|
|
|
170
170
|
if not _is_valid_app_name(data["name"]):
|
|
171
171
|
raise DBOSInitializationError(
|
|
172
|
-
f'Invalid app name {data["name"]}. App names must be between 3 and 30 characters and contain only
|
|
172
|
+
f'Invalid app name {data["name"]}. App names must be between 3 and 30 characters long and contain only lowercase letters, numbers, dashes, and underscores.'
|
|
173
173
|
)
|
|
174
174
|
|
|
175
175
|
if "app_db_name" not in data["database"]:
|
|
@@ -198,4 +198,4 @@ def _app_name_to_db_name(app_name: str) -> str:
|
|
|
198
198
|
def _set_env_vars(config: ConfigFile) -> None:
|
|
199
199
|
for env, value in config.get("env", {}).items():
|
|
200
200
|
if value is not None:
|
|
201
|
-
os.environ[env] = value
|
|
201
|
+
os.environ[env] = str(value)
|
|
@@ -299,6 +299,12 @@ class SystemDatabase:
|
|
|
299
299
|
recovery_attempts: int = row[0]
|
|
300
300
|
if recovery_attempts > max_recovery_attempts:
|
|
301
301
|
with self.engine.begin() as c:
|
|
302
|
+
c.execute(
|
|
303
|
+
sa.delete(SystemSchema.workflow_queue).where(
|
|
304
|
+
SystemSchema.workflow_queue.c.workflow_uuid
|
|
305
|
+
== status["workflow_uuid"]
|
|
306
|
+
)
|
|
307
|
+
)
|
|
302
308
|
c.execute(
|
|
303
309
|
sa.update(SystemSchema.workflow_status)
|
|
304
310
|
.where(
|
|
@@ -311,6 +317,7 @@ class SystemDatabase:
|
|
|
311
317
|
)
|
|
312
318
|
.values(
|
|
313
319
|
status=WorkflowStatusString.RETRIES_EXCEEDED.value,
|
|
320
|
+
queue_name=None,
|
|
314
321
|
)
|
|
315
322
|
)
|
|
316
323
|
raise DBOSDeadLetterQueueError(
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import platform
|
|
3
|
-
import re
|
|
4
3
|
import shutil
|
|
5
4
|
import signal
|
|
6
5
|
import subprocess
|
|
@@ -9,12 +8,15 @@ import typing
|
|
|
9
8
|
from os import path
|
|
10
9
|
from typing import Any
|
|
11
10
|
|
|
11
|
+
import sqlalchemy as sa
|
|
12
12
|
import tomlkit
|
|
13
13
|
import typer
|
|
14
14
|
from rich import print
|
|
15
15
|
from rich.prompt import Prompt
|
|
16
16
|
from typing_extensions import Annotated
|
|
17
17
|
|
|
18
|
+
from dbos._schemas.system_database import SystemSchema
|
|
19
|
+
|
|
18
20
|
from . import load_config
|
|
19
21
|
from ._app_db import ApplicationDatabase
|
|
20
22
|
from ._dbos_config import _is_valid_app_name
|
|
@@ -27,7 +29,9 @@ def _on_windows() -> bool:
|
|
|
27
29
|
return platform.system() == "Windows"
|
|
28
30
|
|
|
29
31
|
|
|
30
|
-
@app.command(
|
|
32
|
+
@app.command(
|
|
33
|
+
help="Start your DBOS application using the start commands in 'dbos-config.yaml'"
|
|
34
|
+
)
|
|
31
35
|
def start() -> None:
|
|
32
36
|
config = load_config()
|
|
33
37
|
start_commands = config["runtimeConfig"]["start"]
|
|
@@ -166,7 +170,7 @@ def _get_project_name() -> typing.Union[str, None]:
|
|
|
166
170
|
return name
|
|
167
171
|
|
|
168
172
|
|
|
169
|
-
@app.command()
|
|
173
|
+
@app.command(help="Initialize a new DBOS application from a template")
|
|
170
174
|
def init(
|
|
171
175
|
project_name: Annotated[
|
|
172
176
|
typing.Optional[str], typer.Argument(help="Specify application name")
|
|
@@ -187,7 +191,9 @@ def init(
|
|
|
187
191
|
)
|
|
188
192
|
|
|
189
193
|
if not _is_valid_app_name(project_name):
|
|
190
|
-
raise Exception(
|
|
194
|
+
raise Exception(
|
|
195
|
+
f"{project_name} is an invalid DBOS app name. App names must be between 3 and 30 characters long and contain only lowercase letters, numbers, dashes, and underscores."
|
|
196
|
+
)
|
|
191
197
|
|
|
192
198
|
templates_dir = _get_templates_directory()
|
|
193
199
|
templates = [x.name for x in os.scandir(templates_dir) if x.is_dir()]
|
|
@@ -212,7 +218,9 @@ def init(
|
|
|
212
218
|
print(f"[red]{e}[/red]")
|
|
213
219
|
|
|
214
220
|
|
|
215
|
-
@app.command(
|
|
221
|
+
@app.command(
|
|
222
|
+
help="Run your database schema migrations using the migration commands in 'dbos-config.yaml'"
|
|
223
|
+
)
|
|
216
224
|
def migrate() -> None:
|
|
217
225
|
config = load_config()
|
|
218
226
|
if not config["database"]["password"]:
|
|
@@ -262,5 +270,68 @@ def migrate() -> None:
|
|
|
262
270
|
typer.echo(f"Completed schema migration for database {app_db_name}")
|
|
263
271
|
|
|
264
272
|
|
|
273
|
+
@app.command(help="Reset the DBOS system database")
|
|
274
|
+
def reset(
|
|
275
|
+
yes: bool = typer.Option(False, "-y", "--yes", help="Skip confirmation prompt")
|
|
276
|
+
) -> None:
|
|
277
|
+
if not yes:
|
|
278
|
+
confirm = typer.confirm(
|
|
279
|
+
"This command resets your DBOS system database, deleting metadata about past workflows and steps. Are you sure you want to proceed?"
|
|
280
|
+
)
|
|
281
|
+
if not confirm:
|
|
282
|
+
typer.echo("Operation cancelled.")
|
|
283
|
+
raise typer.Exit()
|
|
284
|
+
config = load_config()
|
|
285
|
+
sysdb_name = (
|
|
286
|
+
config["database"]["sys_db_name"]
|
|
287
|
+
if "sys_db_name" in config["database"] and config["database"]["sys_db_name"]
|
|
288
|
+
else config["database"]["app_db_name"] + SystemSchema.sysdb_suffix
|
|
289
|
+
)
|
|
290
|
+
postgres_db_url = sa.URL.create(
|
|
291
|
+
"postgresql+psycopg",
|
|
292
|
+
username=config["database"]["username"],
|
|
293
|
+
password=config["database"]["password"],
|
|
294
|
+
host=config["database"]["hostname"],
|
|
295
|
+
port=config["database"]["port"],
|
|
296
|
+
database="postgres",
|
|
297
|
+
)
|
|
298
|
+
try:
|
|
299
|
+
# Connect to postgres default database
|
|
300
|
+
engine = sa.create_engine(postgres_db_url)
|
|
301
|
+
|
|
302
|
+
with engine.connect() as conn:
|
|
303
|
+
# Set autocommit required for database dropping
|
|
304
|
+
conn.execution_options(isolation_level="AUTOCOMMIT")
|
|
305
|
+
|
|
306
|
+
# Terminate existing connections
|
|
307
|
+
conn.execute(
|
|
308
|
+
sa.text(
|
|
309
|
+
"""
|
|
310
|
+
SELECT pg_terminate_backend(pg_stat_activity.pid)
|
|
311
|
+
FROM pg_stat_activity
|
|
312
|
+
WHERE pg_stat_activity.datname = :db_name
|
|
313
|
+
AND pid <> pg_backend_pid()
|
|
314
|
+
"""
|
|
315
|
+
),
|
|
316
|
+
{"db_name": sysdb_name},
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
# Drop the database
|
|
320
|
+
conn.execute(sa.text(f"DROP DATABASE IF EXISTS {sysdb_name}"))
|
|
321
|
+
|
|
322
|
+
except sa.exc.SQLAlchemyError as e:
|
|
323
|
+
typer.echo(f"Error dropping database: {str(e)}")
|
|
324
|
+
return
|
|
325
|
+
|
|
326
|
+
sys_db = None
|
|
327
|
+
try:
|
|
328
|
+
sys_db = SystemDatabase(config)
|
|
329
|
+
except Exception as e:
|
|
330
|
+
typer.echo(f"DBOS system schema migration failed: {e}")
|
|
331
|
+
finally:
|
|
332
|
+
if sys_db:
|
|
333
|
+
sys_db.destroy()
|
|
334
|
+
|
|
335
|
+
|
|
265
336
|
if __name__ == "__main__":
|
|
266
337
|
app()
|
|
@@ -44,6 +44,7 @@ def test_valid_config(mocker):
|
|
|
44
44
|
foo: ${BARBAR}
|
|
45
45
|
bazbaz: BAZBAZ
|
|
46
46
|
bob: ${BOBBOB}
|
|
47
|
+
test_number: 123
|
|
47
48
|
"""
|
|
48
49
|
os.environ["BARBAR"] = "FOOFOO"
|
|
49
50
|
mocker.patch(
|
|
@@ -61,10 +62,12 @@ def test_valid_config(mocker):
|
|
|
61
62
|
assert configFile["database"]["connectionTimeoutMillis"] == 3000
|
|
62
63
|
assert configFile["env"]["foo"] == "FOOFOO"
|
|
63
64
|
assert configFile["env"]["bob"] is None # Unset environment variable
|
|
65
|
+
assert configFile["env"]["test_number"] == 123
|
|
64
66
|
|
|
65
67
|
_set_env_vars(configFile)
|
|
66
68
|
assert os.environ["bazbaz"] == "BAZBAZ"
|
|
67
69
|
assert os.environ["foo"] == "FOOFOO"
|
|
70
|
+
assert os.environ["test_number"] == "123"
|
|
68
71
|
assert "bob" not in os.environ
|
|
69
72
|
|
|
70
73
|
|
|
@@ -8,8 +8,8 @@ from psycopg.errors import SerializationFailure
|
|
|
8
8
|
from sqlalchemy.exc import OperationalError
|
|
9
9
|
|
|
10
10
|
# Public API
|
|
11
|
-
from dbos import DBOS, GetWorkflowsInput, SetWorkflowID
|
|
12
|
-
from dbos._error import DBOSDeadLetterQueueError
|
|
11
|
+
from dbos import DBOS, GetWorkflowsInput, Queue, SetWorkflowID
|
|
12
|
+
from dbos._error import DBOSDeadLetterQueueError
|
|
13
13
|
from dbos._sys_db import WorkflowStatusString
|
|
14
14
|
|
|
15
15
|
|
|
@@ -150,3 +150,44 @@ def test_dead_letter_queue(dbos: DBOS) -> None:
|
|
|
150
150
|
assert handle.get_result() == None
|
|
151
151
|
dbos._sys_db.wait_for_buffer_flush()
|
|
152
152
|
assert handle.get_status().status == WorkflowStatusString.SUCCESS.value
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def test_enqueued_dead_letter_queue(dbos: DBOS) -> None:
|
|
156
|
+
function_started_event = threading.Event()
|
|
157
|
+
event = threading.Event()
|
|
158
|
+
max_concurrency = 1
|
|
159
|
+
max_recovery_attempts = 10
|
|
160
|
+
recovery_count = 0
|
|
161
|
+
|
|
162
|
+
@DBOS.workflow(max_recovery_attempts=max_recovery_attempts)
|
|
163
|
+
def dead_letter_workflow() -> None:
|
|
164
|
+
function_started_event.set()
|
|
165
|
+
nonlocal recovery_count
|
|
166
|
+
recovery_count += 1
|
|
167
|
+
event.wait()
|
|
168
|
+
|
|
169
|
+
@DBOS.workflow()
|
|
170
|
+
def regular_workflow() -> None:
|
|
171
|
+
return
|
|
172
|
+
|
|
173
|
+
queue = Queue("test_queue", concurrency=max_concurrency)
|
|
174
|
+
handle = queue.enqueue(dead_letter_workflow)
|
|
175
|
+
function_started_event.wait()
|
|
176
|
+
|
|
177
|
+
for i in range(max_recovery_attempts):
|
|
178
|
+
DBOS.recover_pending_workflows()
|
|
179
|
+
assert recovery_count == i + 2
|
|
180
|
+
|
|
181
|
+
regular_handle = queue.enqueue(regular_workflow)
|
|
182
|
+
|
|
183
|
+
with pytest.raises(Exception) as exc_info:
|
|
184
|
+
DBOS.recover_pending_workflows()
|
|
185
|
+
assert exc_info.errisinstance(DBOSDeadLetterQueueError)
|
|
186
|
+
assert handle.get_status().status == WorkflowStatusString.RETRIES_EXCEEDED.value
|
|
187
|
+
|
|
188
|
+
assert regular_handle.get_result() == None
|
|
189
|
+
|
|
190
|
+
event.set()
|
|
191
|
+
assert handle.get_result() == None
|
|
192
|
+
dbos._sys_db.wait_for_buffer_flush()
|
|
193
|
+
assert handle.get_status().status == WorkflowStatusString.SUCCESS.value
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_migrations/versions/5c361fc04708_added_system_tables.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dbos-0.13.0a2 → dbos-0.14.0a5}/dbos/_templates/hello/migrations/versions/2024_07_31_180642_init.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|