4141from sqlalchemy .orm import relationship
4242from sqlalchemy .exc import NoResultFound , IntegrityError , OperationalError # noqa: F401
4343
44+ import sqlalchemy_utils
45+
4446LOG = logging .getLogger (__name__ )
4547
4648P = typing .ParamSpec ("P" )
@@ -62,15 +64,19 @@ async def init_engine(db: str, echo=False):
6264 global async_engine , AsyncSessionMaker , ScopedSession
6365
6466 if db .startswith ("sqlite://" ):
65- db = db .replace ("sqlite://" , "sqlite+aiosqlite://" )
67+ adb = db .replace ("sqlite://" , "sqlite+aiosqlite://" )
6668 elif db .startswith ("postgresql://" ):
67- db = db .replace ("postgresql://" , "postgresql+asyncpg://" )
69+ adb = db .replace ("postgresql://" , "postgresql+asyncpg://" )
6870 else :
6971 raise ValueError (
7072 f"Unsupported database dialect: { db } (must be sqlite:// or postgresql://)"
7173 )
7274
73- async_engine = create_async_engine (db , echo = echo )
75+ if not await asyncio .to_thread (sqlalchemy_utils .database_exists , db ):
76+ LOG .warning ("Database does not exist, trying to create it..." )
77+ await asyncio .to_thread (sqlalchemy_utils .create_database , db )
78+
79+ async_engine = create_async_engine (adb , echo = echo )
7480 AsyncSessionMaker = async_sessionmaker (async_engine , expire_on_commit = False )
7581
7682 ScopedSession = async_scoped_session (
0 commit comments