dbos 1.11.0a1__py3-none-any.whl → 1.11.0a3__py3-none-any.whl

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/_app_db.py CHANGED
@@ -74,10 +74,19 @@ class ApplicationDatabase:
74
74
 
75
75
  # Create the dbos schema and transaction_outputs table in the application database
76
76
  with self.engine.begin() as conn:
77
- schema_creation_query = sa.text(
78
- f"CREATE SCHEMA IF NOT EXISTS {ApplicationSchema.schema}"
79
- )
80
- conn.execute(schema_creation_query)
77
+ # Check if schema exists first
78
+ schema_exists = conn.execute(
79
+ sa.text(
80
+ "SELECT 1 FROM information_schema.schemata WHERE schema_name = :schema_name"
81
+ ),
82
+ parameters={"schema_name": ApplicationSchema.schema},
83
+ ).scalar()
84
+
85
+ if not schema_exists:
86
+ schema_creation_query = sa.text(
87
+ f"CREATE SCHEMA {ApplicationSchema.schema}"
88
+ )
89
+ conn.execute(schema_creation_query)
81
90
 
82
91
  inspector = inspect(self.engine)
83
92
  if not inspector.has_table(
dbos/cli/cli.py CHANGED
@@ -15,6 +15,7 @@ from rich.prompt import IntPrompt
15
15
  from typing_extensions import Annotated, List
16
16
 
17
17
  from dbos._debug import debug_workflow, parse_start_command
18
+ from dbos.cli.migration import grant_dbos_schema_permissions, migrate_dbos_databases
18
19
 
19
20
  from .._app_db import ApplicationDatabase
20
21
  from .._client import DBOSClient
@@ -278,6 +279,14 @@ def migrate(
278
279
  help="Your DBOS system database URL",
279
280
  ),
280
281
  ] = None,
282
+ application_role: Annotated[
283
+ typing.Optional[str],
284
+ typer.Option(
285
+ "--app-role",
286
+ "-r",
287
+ help="The role with which you will run your DBOS application",
288
+ ),
289
+ ] = None,
281
290
  ) -> None:
282
291
  app_database_url = _get_db_url(app_database_url)
283
292
  system_database_url = get_system_database_url(
@@ -293,37 +302,18 @@ def migrate(
293
302
  typer.echo(f"System database: {sa.make_url(system_database_url)}")
294
303
 
295
304
  # First, run DBOS migrations on the system database and the application database
296
- app_db = None
297
- sys_db = None
298
- try:
299
- sys_db = SystemDatabase(
300
- system_database_url=system_database_url,
301
- engine_kwargs={
302
- "pool_timeout": 30,
303
- "max_overflow": 0,
304
- "pool_size": 2,
305
- },
305
+ migrate_dbos_databases(
306
+ app_database_url=app_database_url, system_database_url=system_database_url
307
+ )
308
+
309
+ # Next, assign permissions on the DBOS schema to the application role, if any
310
+ if application_role:
311
+ grant_dbos_schema_permissions(
312
+ database_url=app_database_url, role_name=application_role
306
313
  )
307
- app_db = ApplicationDatabase(
308
- database_url=app_database_url,
309
- engine_kwargs={
310
- "pool_timeout": 30,
311
- "max_overflow": 0,
312
- "pool_size": 2,
313
- },
314
+ grant_dbos_schema_permissions(
315
+ database_url=system_database_url, role_name=application_role
314
316
  )
315
- sys_db.run_migrations()
316
- app_db.run_migrations()
317
- except Exception as e:
318
- typer.echo(f"DBOS migrations failed: {e}")
319
- raise typer.Exit(code=1)
320
- finally:
321
- if sys_db:
322
- sys_db.destroy()
323
- if app_db:
324
- app_db.destroy()
325
-
326
- typer.echo(f"DBOS migrations successful")
327
317
 
328
318
  # Next, run any custom migration commands specified in the configuration
329
319
  if os.path.exists("dbos-config.yaml"):
dbos/cli/migration.py ADDED
@@ -0,0 +1,93 @@
1
+ import sqlalchemy as sa
2
+ import typer
3
+
4
+ from dbos._app_db import ApplicationDatabase
5
+ from dbos._sys_db import SystemDatabase
6
+
7
+
8
+ def migrate_dbos_databases(app_database_url: str, system_database_url: str) -> None:
9
+ app_db = None
10
+ sys_db = None
11
+ try:
12
+ sys_db = SystemDatabase(
13
+ system_database_url=system_database_url,
14
+ engine_kwargs={
15
+ "pool_timeout": 30,
16
+ "max_overflow": 0,
17
+ "pool_size": 2,
18
+ },
19
+ )
20
+ app_db = ApplicationDatabase(
21
+ database_url=app_database_url,
22
+ engine_kwargs={
23
+ "pool_timeout": 30,
24
+ "max_overflow": 0,
25
+ "pool_size": 2,
26
+ },
27
+ )
28
+ sys_db.run_migrations()
29
+ app_db.run_migrations()
30
+ except Exception as e:
31
+ typer.echo(f"DBOS migrations failed: {e}")
32
+ raise typer.Exit(code=1)
33
+ finally:
34
+ if sys_db:
35
+ sys_db.destroy()
36
+ if app_db:
37
+ app_db.destroy()
38
+
39
+
40
+ def grant_dbos_schema_permissions(database_url: str, role_name: str) -> None:
41
+ """
42
+ Grant all permissions on all entities in the dbos schema to the specified role.
43
+ """
44
+ typer.echo(
45
+ f"Granting permissions for DBOS schema to {role_name} in database {sa.make_url(database_url)}"
46
+ )
47
+ engine = None
48
+ try:
49
+ engine = sa.create_engine(database_url)
50
+ with engine.connect() as connection:
51
+ connection.execution_options(isolation_level="AUTOCOMMIT")
52
+
53
+ # Grant usage on the dbos schema
54
+ sql = f'GRANT USAGE ON SCHEMA dbos TO "{role_name}"'
55
+ typer.echo(sql)
56
+ connection.execute(sa.text(sql))
57
+
58
+ # Grant all privileges on all existing tables in dbos schema (includes views)
59
+ sql = f'GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA dbos TO "{role_name}"'
60
+ typer.echo(sql)
61
+ connection.execute(sa.text(sql))
62
+
63
+ # Grant all privileges on all sequences in dbos schema
64
+ sql = (
65
+ f'GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA dbos TO "{role_name}"'
66
+ )
67
+ typer.echo(sql)
68
+ connection.execute(sa.text(sql))
69
+
70
+ # Grant execute on all functions and procedures in dbos schema
71
+ sql = f'GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA dbos TO "{role_name}"'
72
+ typer.echo(sql)
73
+ connection.execute(sa.text(sql))
74
+
75
+ # Grant default privileges for future objects in dbos schema
76
+ sql = f'ALTER DEFAULT PRIVILEGES IN SCHEMA dbos GRANT ALL ON TABLES TO "{role_name}"'
77
+ typer.echo(sql)
78
+ connection.execute(sa.text(sql))
79
+
80
+ sql = f'ALTER DEFAULT PRIVILEGES IN SCHEMA dbos GRANT ALL ON SEQUENCES TO "{role_name}"'
81
+ typer.echo(sql)
82
+ connection.execute(sa.text(sql))
83
+
84
+ sql = f'ALTER DEFAULT PRIVILEGES IN SCHEMA dbos GRANT EXECUTE ON FUNCTIONS TO "{role_name}"'
85
+ typer.echo(sql)
86
+ connection.execute(sa.text(sql))
87
+
88
+ except Exception as e:
89
+ typer.echo(f"Failed to grant permissions to role {role_name}: {e}")
90
+ raise typer.Exit(code=1)
91
+ finally:
92
+ if engine:
93
+ engine.dispose()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dbos
3
- Version: 1.11.0a1
3
+ Version: 1.11.0a3
4
4
  Summary: Ultra-lightweight durable execution in Python
5
5
  Author-Email: "DBOS, Inc." <contact@dbos.dev>
6
6
  License: MIT
@@ -1,11 +1,11 @@
1
- dbos-1.11.0a1.dist-info/METADATA,sha256=T1r9u-NqfAWkMSlkExVKMRfwVIsYUT-ucsDTYFKTxss,13268
2
- dbos-1.11.0a1.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
- dbos-1.11.0a1.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
4
- dbos-1.11.0a1.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
1
+ dbos-1.11.0a3.dist-info/METADATA,sha256=bYxL7G7Lu7GMz4D-PoDMfFTGF1yL4C4ErS5ns8AjIbI,13268
2
+ dbos-1.11.0a3.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
+ dbos-1.11.0a3.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
4
+ dbos-1.11.0a3.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
5
5
  dbos/__init__.py,sha256=NssPCubaBxdiKarOWa-wViz1hdJSkmBGcpLX_gQ4NeA,891
6
6
  dbos/__main__.py,sha256=G7Exn-MhGrVJVDbgNlpzhfh8WMX_72t3_oJaFT9Lmt8,653
7
7
  dbos/_admin_server.py,sha256=e8ELhcDWqR3_PNobnNgUvLGh5lzZq0yFSF6dvtzoQRI,16267
8
- dbos/_app_db.py,sha256=htblDPfqrpb_uZoFcvaud7cgQ-PDyn6Bn-cBidxdCTA,10603
8
+ dbos/_app_db.py,sha256=bUXQqzc0C9PHh4Zl2tHfBrQWNBURdI7F7XXjCpYirmw,10959
9
9
  dbos/_classproperty.py,sha256=f0X-_BySzn3yFDRKB2JpCbLYQ9tLwt1XftfshvY7CBs,626
10
10
  dbos/_client.py,sha256=_wMe4qnRSwiRZo74xdqTBetbHlIVy3vQifdSd7os1ZY,18213
11
11
  dbos/_conductor/conductor.py,sha256=3E_hL3c9g9yWqKZkvI6KA0-ZzPMPRo06TOzT1esMiek,24114
@@ -66,8 +66,9 @@ dbos/_utils.py,sha256=uywq1QrjMwy17btjxW4bES49povlQwYwYbvKwMT6C2U,1575
66
66
  dbos/_workflow_commands.py,sha256=EmmAaQfRWeOZm_WPTznuU-O3he3jiSzzT9VpYrhxugE,4835
67
67
  dbos/cli/_github_init.py,sha256=Y_bDF9gfO2jB1id4FV5h1oIxEJRWyqVjhb7bNEa5nQ0,3224
68
68
  dbos/cli/_template_init.py,sha256=7JBcpMqP1r2mfCnvWatu33z8ctEGHJarlZYKgB83cXE,2972
69
- dbos/cli/cli.py,sha256=BaWqdMZbUsJkq0zEaS2Ez2FgRgD5nTD24hCsrAlitbA,22289
69
+ dbos/cli/cli.py,sha256=ey7E-lNFgvUWhsd-mkFwZvTdYorv6hU2zsMOS23n1yQ,22214
70
+ dbos/cli/migration.py,sha256=vUgBXqde1eYATd1ncBeT1iJZMO6lrcofn8-s9J9__Xo,3244
70
71
  dbos/dbos-config.schema.json,sha256=CjaspeYmOkx6Ip_pcxtmfXJTn_YGdSx_0pcPBF7KZmo,6060
71
72
  dbos/py.typed,sha256=QfzXT1Ktfk3Rj84akygc7_42z0lRpCq0Ilh8OXI6Zas,44
72
73
  version/__init__.py,sha256=L4sNxecRuqdtSFdpUGX3TtBi9KL3k7YsZVIvv-fv9-A,1678
73
- dbos-1.11.0a1.dist-info/RECORD,,
74
+ dbos-1.11.0a3.dist-info/RECORD,,