Repository navigation
Expand file tree
/
Copy pathdatabase.py
More file actions
41 lines (33 loc) 路 1.44 KB
/
Copy pathdatabase.py
File metadata and controls
41 lines (33 loc) 路 1.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import os
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
from sqlalchemy.orm import declarative_base
from dotenv import load_dotenv
load_dotenv()
# Ensure the instance directory exists
os.makedirs('instance', exist_ok=True)
# Convert a plain sqlite:// URL to the async sqlite+aiosqlite:// driver.
# This lets DATABASE_URL be set as a plain sqlite:// in the environment without
# requiring the caller to know about the aiosqlite driver suffix.
_raw_url = os.environ.get('DATABASE_URL', 'sqlite:///instance/courses.db')
if _raw_url.startswith('sqlite://') and '+aiosqlite' not in _raw_url:
SQLALCHEMY_DATABASE_URL = _raw_url.replace('sqlite://', 'sqlite+aiosqlite://', 1)
else:
SQLALCHEMY_DATABASE_URL = _raw_url
engine = create_async_engine(
SQLALCHEMY_DATABASE_URL,
echo=False,
# aiosqlite manages thread-safety internally; check_same_thread is not applicable
# For PostgreSQL async, remove the connect_args kwarg entirely.
)
# expire_on_commit=False prevents SQLAlchemy from expiring loaded attributes after commit,
# which would require a second DB round-trip to access them again in async context.
AsyncSessionLocal = async_sessionmaker(
engine,
class_=AsyncSession,
expire_on_commit=False,
)
Base = declarative_base()
async def get_db():
"""FastAPI dependency that yields an AsyncSession and guarantees cleanup."""
async with AsyncSessionLocal() as session:
yield session