|
5 | 5 |
|
6 | 6 | from fastapi import Depends |
7 | 7 | from sqlalchemy import event |
8 | | -from sqlalchemy.engine import make_url |
| 8 | +from sqlalchemy.engine import URL, make_url |
9 | 9 | from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, create_async_engine |
10 | 10 | from sqlalchemy.pool import AsyncAdaptedQueuePool |
11 | 11 |
|
@@ -55,18 +55,14 @@ async def __aexit__(self, *excinfo): |
55 | 55 |
|
56 | 56 |
|
57 | 57 | def open_database_connection_pool(database_settings: DatabaseSettings) -> AsyncEngine: |
58 | | - if make_url(database_settings.uri).database == ":memory:": |
59 | | - # For SQLite databases that exist only in process memory, |
60 | | - # pooling is not applicable. Just return an engine and don't cache it. |
| 58 | + if is_memory_sqlite(database_settings.uri): |
61 | 59 | engine = create_async_engine( |
62 | 60 | ensure_specified_sql_driver(database_settings.uri), |
63 | 61 | echo=DEFAULT_ECHO, |
64 | 62 | json_serializer=json_serializer, |
65 | 63 | ) |
66 | 64 |
|
67 | 65 | else: |
68 | | - # For file-backed SQLite databases, and for PostgreSQL databases, |
69 | | - # connection pooling offers a significant performance boost. |
70 | 66 | engine = create_async_engine( |
71 | 67 | ensure_specified_sql_driver(database_settings.uri), |
72 | 68 | echo=DEFAULT_ECHO, |
@@ -137,3 +133,34 @@ def _set_sqlite_pragma(conn, record): |
137 | 133 | cursor = conn.cursor() |
138 | 134 | cursor.execute("PRAGMA foreign_keys=ON") |
139 | 135 | cursor.close() |
| 136 | + |
| 137 | + |
| 138 | +def is_memory_sqlite(url: Union[URL, str]) -> bool: |
| 139 | + """ |
| 140 | + Check if a SQLAlchemy URL is a memory-backed SQLite database. |
| 141 | +
|
| 142 | + Handles various memory database URL formats: |
| 143 | + - sqlite:///:memory: |
| 144 | + - sqlite:///file::memory:?cache=shared |
| 145 | + - sqlite:// |
| 146 | + - etc. |
| 147 | + """ |
| 148 | + url = make_url(url) |
| 149 | + # Check if it's SQLite at all |
| 150 | + if url.get_dialect().name != "sqlite": |
| 151 | + return False |
| 152 | + |
| 153 | + # Check if database is None or empty (default memory DB) |
| 154 | + if not url.database: |
| 155 | + return True |
| 156 | + |
| 157 | + # Check for explicit :memory: string (case-insensitive) |
| 158 | + database = str(url.database).lower() |
| 159 | + if ":memory:" in database: |
| 160 | + return True |
| 161 | + |
| 162 | + # Check for mode=memory query parameter |
| 163 | + if (mode := url.query.get("mode")) and mode.lower() == "memory": |
| 164 | + return True |
| 165 | + |
| 166 | + return False |
0 commit comments