From 3cbebbb8a23a8aaffa6568235bf498918fc73226 Mon Sep 17 00:00:00 2001 From: zhucong Date: Wed, 18 Sep 2024 17:51:41 +0800 Subject: [PATCH 1/3] Add create shcmea for sqlalchemy datastore --- docs/versionhistory.rst | 2 ++ src/apscheduler/datastores/sqlalchemy.py | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/docs/versionhistory.rst b/docs/versionhistory.rst index e8eda3c1..a2ddbb2a 100644 --- a/docs/versionhistory.rst +++ b/docs/versionhistory.rst @@ -60,6 +60,8 @@ APScheduler, see the :doc:`migration section `. useful and reasonable - Fixed race condition in ``MongoDBDataStore`` that allowed multiple schedulers to acquire the same schedules at once +- Changed ``SQLAlchemyDataStore`` to automatically create the explicitly specified + schema if it's missing **4.0.0a5** diff --git a/src/apscheduler/datastores/sqlalchemy.py b/src/apscheduler/datastores/sqlalchemy.py index dd680a87..343d9b2e 100644 --- a/src/apscheduler/datastores/sqlalchemy.py +++ b/src/apscheduler/datastores/sqlalchemy.py @@ -48,6 +48,7 @@ ) from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine, create_async_engine from sqlalchemy.future import Connection, Engine +from sqlalchemy.schema import CreateSchema from sqlalchemy.sql import Executable from sqlalchemy.sql.ddl import DropTable from sqlalchemy.sql.elements import BindParameter, literal @@ -231,6 +232,12 @@ async def _begin_transaction( yield conn + async def _create_schema(self, conn: Connection | AsyncConnection) -> None: + if not self.schema: + return + t = CreateSchema(name=self.schema, if_not_exists=True) + await self._execute(conn, t) + async def _create_metadata(self, conn: Connection | AsyncConnection) -> None: if isinstance(conn, AsyncConnection): await conn.run_sync(self._metadata.create_all) @@ -389,6 +396,7 @@ async def start( async for attempt in self._retry(): with attempt: async with self._begin_transaction() as conn: + await self._create_schema(conn) if self.start_from_scratch: for table in self._metadata.sorted_tables: await self._execute(conn, DropTable(table, if_exists=True)) From 2469de7909feedc1b5b4636665a29f68b50a67f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= Date: Sun, 22 Sep 2024 19:23:24 +0300 Subject: [PATCH 2/3] Added attribution to the changelog --- docs/versionhistory.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/versionhistory.rst b/docs/versionhistory.rst index a2ddbb2a..9614762c 100644 --- a/docs/versionhistory.rst +++ b/docs/versionhistory.rst @@ -61,7 +61,7 @@ APScheduler, see the :doc:`migration section `. - Fixed race condition in ``MongoDBDataStore`` that allowed multiple schedulers to acquire the same schedules at once - Changed ``SQLAlchemyDataStore`` to automatically create the explicitly specified - schema if it's missing + schema if it's missing (PR by @zhu0629) **4.0.0a5** From c44876e5fd7c0ec34d01d51877de844734cac583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= Date: Sun, 22 Sep 2024 19:35:55 +0300 Subject: [PATCH 3/3] Moved the code from _create_schema() to start() --- src/apscheduler/datastores/sqlalchemy.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/apscheduler/datastores/sqlalchemy.py b/src/apscheduler/datastores/sqlalchemy.py index 343d9b2e..0c4e8d74 100644 --- a/src/apscheduler/datastores/sqlalchemy.py +++ b/src/apscheduler/datastores/sqlalchemy.py @@ -232,12 +232,6 @@ async def _begin_transaction( yield conn - async def _create_schema(self, conn: Connection | AsyncConnection) -> None: - if not self.schema: - return - t = CreateSchema(name=self.schema, if_not_exists=True) - await self._execute(conn, t) - async def _create_metadata(self, conn: Connection | AsyncConnection) -> None: if isinstance(conn, AsyncConnection): await conn.run_sync(self._metadata.create_all) @@ -396,7 +390,12 @@ async def start( async for attempt in self._retry(): with attempt: async with self._begin_transaction() as conn: - await self._create_schema(conn) + # Create the schema first if it doesn't exist yet + if self.schema: + await self._execute( + conn, CreateSchema(name=self.schema, if_not_exists=True) + ) + if self.start_from_scratch: for table in self._metadata.sorted_tables: await self._execute(conn, DropTable(table, if_exists=True))