sqlspec 0.62.0__py3-none-any.whl → 0.62.2__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.
- sqlspec/adapters/asyncmy/adk/store.py +7 -6
- sqlspec/adapters/asyncmy/config.py +1 -1
- sqlspec/adapters/asyncmy/litestar/store.py +2 -1
- sqlspec/adapters/asyncpg/adk/store.py +14 -8
- sqlspec/adapters/asyncpg/config.py +20 -1
- sqlspec/adapters/psycopg/adk/store.py +21 -13
- sqlspec/adapters/psycopg/config.py +40 -2
- sqlspec/builder/_ddl.py +7 -5
- sqlspec/config.py +2 -2
- sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +20 -9
- sqlspec/extensions/litestar/plugin.py +12 -3
- {sqlspec-0.62.0.dist-info → sqlspec-0.62.2.dist-info}/METADATA +1 -1
- {sqlspec-0.62.0.dist-info → sqlspec-0.62.2.dist-info}/RECORD +16 -16
- {sqlspec-0.62.0.dist-info → sqlspec-0.62.2.dist-info}/WHEEL +0 -0
- {sqlspec-0.62.0.dist-info → sqlspec-0.62.2.dist-info}/entry_points.txt +0 -0
- {sqlspec-0.62.0.dist-info → sqlspec-0.62.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -7,6 +7,7 @@ from typing import TYPE_CHECKING, Any, Final, Literal, cast
|
|
|
7
7
|
import asyncmy
|
|
8
8
|
from typing_extensions import NotRequired
|
|
9
9
|
|
|
10
|
+
from sqlspec.adapters.asyncmy.core import resolve_rowcount
|
|
10
11
|
from sqlspec.config import ADKConfig
|
|
11
12
|
from sqlspec.extensions.adk import BaseAsyncADKStore, StoredEvent, StoredSession, normalize_session_list_options
|
|
12
13
|
from sqlspec.extensions.adk.memory.store import BaseAsyncADKMemoryStore
|
|
@@ -309,7 +310,7 @@ class AsyncmyADKStore(BaseAsyncADKStore["AsyncmyConfig"]):
|
|
|
309
310
|
async with self._config.provide_connection() as conn, conn.cursor() as cursor:
|
|
310
311
|
await cursor.execute(sql, tuple(params))
|
|
311
312
|
await conn.commit()
|
|
312
|
-
return cursor
|
|
313
|
+
return resolve_rowcount(cursor)
|
|
313
314
|
except asyncmy.errors.ProgrammingError as exc: # pyright: ignore[reportAttributeAccessIssue]
|
|
314
315
|
if _is_mysql_table_missing(exc):
|
|
315
316
|
return 0
|
|
@@ -327,7 +328,7 @@ class AsyncmyADKStore(BaseAsyncADKStore["AsyncmyConfig"]):
|
|
|
327
328
|
async with self._config.provide_connection() as conn, conn.cursor() as cursor:
|
|
328
329
|
await cursor.execute(sql, tuple(params))
|
|
329
330
|
await conn.commit()
|
|
330
|
-
return cursor
|
|
331
|
+
return resolve_rowcount(cursor)
|
|
331
332
|
except asyncmy.errors.ProgrammingError as exc: # pyright: ignore[reportAttributeAccessIssue]
|
|
332
333
|
if _is_mysql_table_missing(exc):
|
|
333
334
|
return 0
|
|
@@ -345,7 +346,7 @@ class AsyncmyADKStore(BaseAsyncADKStore["AsyncmyConfig"]):
|
|
|
345
346
|
async with self._config.provide_connection() as conn, conn.cursor() as cursor:
|
|
346
347
|
await cursor.execute(sql, tuple(params))
|
|
347
348
|
await conn.commit()
|
|
348
|
-
return cursor
|
|
349
|
+
return resolve_rowcount(cursor)
|
|
349
350
|
except asyncmy.errors.ProgrammingError as exc: # pyright: ignore[reportAttributeAccessIssue]
|
|
350
351
|
if _is_mysql_table_missing(exc):
|
|
351
352
|
return 0
|
|
@@ -545,7 +546,7 @@ class AsyncmyADKMemoryStore(BaseAsyncADKMemoryStore["AsyncmyConfig"]):
|
|
|
545
546
|
entry["inserted_at"],
|
|
546
547
|
)
|
|
547
548
|
await cursor.execute(sql, params)
|
|
548
|
-
inserted_count += cursor
|
|
549
|
+
inserted_count += resolve_rowcount(cursor)
|
|
549
550
|
await conn.commit()
|
|
550
551
|
return inserted_count
|
|
551
552
|
|
|
@@ -608,7 +609,7 @@ class AsyncmyADKMemoryStore(BaseAsyncADKMemoryStore["AsyncmyConfig"]):
|
|
|
608
609
|
async with self._config.provide_connection() as conn, conn.cursor() as cursor:
|
|
609
610
|
await cursor.execute(sql, (session_id,))
|
|
610
611
|
await conn.commit()
|
|
611
|
-
return cursor
|
|
612
|
+
return resolve_rowcount(cursor)
|
|
612
613
|
|
|
613
614
|
async def delete_entries_older_than(
|
|
614
615
|
self, days: int, app_name: "str | None" = None, scope: "str | None" = None
|
|
@@ -632,7 +633,7 @@ class AsyncmyADKMemoryStore(BaseAsyncADKMemoryStore["AsyncmyConfig"]):
|
|
|
632
633
|
async with self._config.provide_connection() as conn, conn.cursor() as cursor:
|
|
633
634
|
await cursor.execute(sql, tuple(params))
|
|
634
635
|
await conn.commit()
|
|
635
|
-
return cursor
|
|
636
|
+
return resolve_rowcount(cursor)
|
|
636
637
|
|
|
637
638
|
async def _memory_table_ddl(self) -> str:
|
|
638
639
|
"""Get MySQL CREATE TABLE SQL for memory entries."""
|
|
@@ -325,7 +325,7 @@ class AsyncmyConfig(AsyncDatabaseConfig[AsyncmyConnection, "AsyncmyPool", Asyncm
|
|
|
325
325
|
|
|
326
326
|
Future driver_features can be added here if needed.
|
|
327
327
|
"""
|
|
328
|
-
return
|
|
328
|
+
return await asyncmy.create_pool(**_pool_config(self.connection_config))
|
|
329
329
|
|
|
330
330
|
async def _ensure_connection(self, connection: "AsyncmyConnection") -> None:
|
|
331
331
|
"""Ensure connection callback has been called exactly once for this connection.
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from datetime import datetime, timedelta, timezone
|
|
4
4
|
from typing import TYPE_CHECKING, Any, Final, cast
|
|
5
5
|
|
|
6
|
+
from sqlspec.adapters.asyncmy.core import resolve_rowcount
|
|
6
7
|
from sqlspec.exceptions import ImproperConfigurationError
|
|
7
8
|
from sqlspec.extensions.litestar.store import BaseSQLSpecStore
|
|
8
9
|
from sqlspec.utils.logging import get_logger
|
|
@@ -227,7 +228,7 @@ class AsyncmyStore(BaseSQLSpecStore["AsyncmyConfig"]):
|
|
|
227
228
|
async with self._config.provide_connection() as conn, conn.cursor() as cursor:
|
|
228
229
|
await cursor.execute(sql)
|
|
229
230
|
await conn.commit()
|
|
230
|
-
count
|
|
231
|
+
count = resolve_rowcount(cursor)
|
|
231
232
|
if count > 0:
|
|
232
233
|
self._log_delete_expired(count)
|
|
233
234
|
return count
|
|
@@ -599,6 +599,8 @@ class AsyncpgADKMemoryStore(BaseAsyncADKMemoryStore["AsyncpgConfig"]):
|
|
|
599
599
|
return
|
|
600
600
|
|
|
601
601
|
async with self._config.provide_session() as driver:
|
|
602
|
+
if self._enable_bm25:
|
|
603
|
+
self._config._ensure_pg_textsearch_available()
|
|
602
604
|
await driver.execute_script(await self._memory_table_ddl())
|
|
603
605
|
|
|
604
606
|
async def insert_memory_entries(self, entries: "list[StoredMemory]", owner_id: "object | None" = None) -> int:
|
|
@@ -616,9 +618,9 @@ class AsyncpgADKMemoryStore(BaseAsyncADKMemoryStore["AsyncpgConfig"]):
|
|
|
616
618
|
sql = f"""
|
|
617
619
|
INSERT INTO {self._memory_table}
|
|
618
620
|
(id, session_id, app_name, user_id, scope, event_id, author,
|
|
619
|
-
{self._owner_id_column_name}, timestamp, content_json,
|
|
621
|
+
{self._owner_id_column_name}, timestamp, embedding, content_json,
|
|
620
622
|
content_text, metadata_json, inserted_at)
|
|
621
|
-
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
|
|
623
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10::float8[]::vector, $11, $12, $13, $14)
|
|
622
624
|
ON CONFLICT (event_id) DO NOTHING
|
|
623
625
|
"""
|
|
624
626
|
result = await conn.execute(
|
|
@@ -632,6 +634,7 @@ class AsyncpgADKMemoryStore(BaseAsyncADKMemoryStore["AsyncpgConfig"]):
|
|
|
632
634
|
entry["author"],
|
|
633
635
|
owner_id,
|
|
634
636
|
entry["timestamp"],
|
|
637
|
+
entry.get("embedding"),
|
|
635
638
|
entry["content_json"],
|
|
636
639
|
entry["content_text"],
|
|
637
640
|
entry["metadata_json"],
|
|
@@ -641,8 +644,8 @@ class AsyncpgADKMemoryStore(BaseAsyncADKMemoryStore["AsyncpgConfig"]):
|
|
|
641
644
|
sql = f"""
|
|
642
645
|
INSERT INTO {self._memory_table}
|
|
643
646
|
(id, session_id, app_name, user_id, scope, event_id, author,
|
|
644
|
-
timestamp, content_json, content_text, metadata_json, inserted_at)
|
|
645
|
-
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
|
647
|
+
timestamp, embedding, content_json, content_text, metadata_json, inserted_at)
|
|
648
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::float8[]::vector, $10, $11, $12, $13)
|
|
646
649
|
ON CONFLICT (event_id) DO NOTHING
|
|
647
650
|
"""
|
|
648
651
|
result = await conn.execute(
|
|
@@ -655,13 +658,14 @@ class AsyncpgADKMemoryStore(BaseAsyncADKMemoryStore["AsyncpgConfig"]):
|
|
|
655
658
|
entry["event_id"],
|
|
656
659
|
entry["author"],
|
|
657
660
|
entry["timestamp"],
|
|
661
|
+
entry.get("embedding"),
|
|
658
662
|
entry["content_json"],
|
|
659
663
|
entry["content_text"],
|
|
660
664
|
entry["metadata_json"],
|
|
661
665
|
entry["inserted_at"],
|
|
662
666
|
)
|
|
663
667
|
try:
|
|
664
|
-
inserted_count += int(result.
|
|
668
|
+
inserted_count += int(result.rsplit(" ", 1)[-1])
|
|
665
669
|
except (IndexError, ValueError):
|
|
666
670
|
continue
|
|
667
671
|
|
|
@@ -706,7 +710,7 @@ class AsyncpgADKMemoryStore(BaseAsyncADKMemoryStore["AsyncpgConfig"]):
|
|
|
706
710
|
candidate_limit = max(limit_value * 2, 50)
|
|
707
711
|
sql = f"""
|
|
708
712
|
WITH vector_matches AS (
|
|
709
|
-
SELECT id, RANK() OVER (ORDER BY embedding <=> {p_vec}) AS rank_vec
|
|
713
|
+
SELECT id, RANK() OVER (ORDER BY embedding <=> {p_vec}::float8[]::vector) AS rank_vec
|
|
710
714
|
FROM {self._memory_table}
|
|
711
715
|
WHERE {where_scope} AND embedding IS NOT NULL
|
|
712
716
|
LIMIT {p_cand}
|
|
@@ -732,7 +736,7 @@ class AsyncpgADKMemoryStore(BaseAsyncADKMemoryStore["AsyncpgConfig"]):
|
|
|
732
736
|
sql = f"""
|
|
733
737
|
SELECT * FROM {self._memory_table}
|
|
734
738
|
WHERE {where_scope} AND embedding IS NOT NULL
|
|
735
|
-
ORDER BY embedding <=> {p_vec} ASC, timestamp DESC
|
|
739
|
+
ORDER BY embedding <=> {p_vec}::float8[]::vector ASC, timestamp DESC
|
|
736
740
|
LIMIT {p_lim}
|
|
737
741
|
"""
|
|
738
742
|
params = (*scope_params, list(embedding), limit_value)
|
|
@@ -759,6 +763,8 @@ class AsyncpgADKMemoryStore(BaseAsyncADKMemoryStore["AsyncpgConfig"]):
|
|
|
759
763
|
params = (*scope_params, f"%{query}%", limit_value)
|
|
760
764
|
|
|
761
765
|
async with self._config.provide_connection() as conn:
|
|
766
|
+
if embedding is not None and self._enable_bm25 and query:
|
|
767
|
+
self._config._ensure_pg_textsearch_available()
|
|
762
768
|
rows = await conn.fetch(sql, *params)
|
|
763
769
|
return [cast("StoredMemory", dict(row)) for row in rows]
|
|
764
770
|
|
|
@@ -821,7 +827,7 @@ class AsyncpgADKMemoryStore(BaseAsyncADKMemoryStore["AsyncpgConfig"]):
|
|
|
821
827
|
|
|
822
828
|
if self._enable_bm25:
|
|
823
829
|
indexes.append(
|
|
824
|
-
f"CREATE INDEX IF NOT EXISTS idx_{self._memory_table}_bm25 ON {self._memory_table} USING bm25 (content_text);"
|
|
830
|
+
f"CREATE INDEX IF NOT EXISTS idx_{self._memory_table}_bm25 ON {self._memory_table} USING bm25 (content_text) WITH (text_config='english');"
|
|
825
831
|
)
|
|
826
832
|
|
|
827
833
|
if self._vector_index_type == "scann":
|
|
@@ -326,6 +326,8 @@ class AsyncpgConfig(AsyncDatabaseConfig[AsyncpgConnection, "Pool[Record]", Async
|
|
|
326
326
|
self._alloydb_connector: Any | None = None
|
|
327
327
|
self._pgvector_available: bool | None = None
|
|
328
328
|
self._paradedb_available: bool | None = None
|
|
329
|
+
self._pg_textsearch_available: bool | None = None
|
|
330
|
+
self._pg_textsearch_probe_error: Exception | None = None
|
|
329
331
|
|
|
330
332
|
self._validate_connector_config()
|
|
331
333
|
|
|
@@ -452,17 +454,28 @@ class AsyncpgConfig(AsyncDatabaseConfig[AsyncpgConnection, "Pool[Record]", Async
|
|
|
452
454
|
if self._pgvector_available is None:
|
|
453
455
|
detected_extensions: set[str] = set()
|
|
454
456
|
extensions = build_postgres_extension_probe_names(self.driver_features)
|
|
457
|
+
adk_config = self.extension_config.get("adk", {})
|
|
458
|
+
bm25_enabled = bool(
|
|
459
|
+
isinstance(adk_config, dict)
|
|
460
|
+
and adk_config.get("enable_memory", True)
|
|
461
|
+
and adk_config.get("enable_bm25", False)
|
|
462
|
+
)
|
|
463
|
+
if bm25_enabled:
|
|
464
|
+
extensions.append("pg_textsearch")
|
|
455
465
|
if extensions:
|
|
456
466
|
try:
|
|
457
467
|
results = await connection.fetch(
|
|
458
468
|
"SELECT extname FROM pg_extension WHERE extname = ANY($1::text[])", extensions
|
|
459
469
|
)
|
|
460
470
|
detected_extensions = {r["extname"] for r in results}
|
|
461
|
-
except Exception:
|
|
471
|
+
except Exception as exc:
|
|
462
472
|
detected_extensions = set()
|
|
473
|
+
if bm25_enabled:
|
|
474
|
+
self._pg_textsearch_probe_error = exc
|
|
463
475
|
self.statement_config, self._pgvector_available, self._paradedb_available = (
|
|
464
476
|
resolve_postgres_extension_state(self.statement_config, self.driver_features, detected_extensions)
|
|
465
477
|
)
|
|
478
|
+
self._pg_textsearch_available = "pg_textsearch" in detected_extensions if bm25_enabled else False
|
|
466
479
|
|
|
467
480
|
if self._pgvector_available:
|
|
468
481
|
await register_pgvector_support(connection)
|
|
@@ -471,6 +484,12 @@ class AsyncpgConfig(AsyncDatabaseConfig[AsyncpgConnection, "Pool[Record]", Async
|
|
|
471
484
|
if self._user_connection_hook is not None:
|
|
472
485
|
await self._user_connection_hook(connection)
|
|
473
486
|
|
|
487
|
+
def _ensure_pg_textsearch_available(self) -> None:
|
|
488
|
+
if self._pg_textsearch_available:
|
|
489
|
+
return
|
|
490
|
+
msg = "ADK memory enable_bm25 requires the pg_textsearch PostgreSQL extension"
|
|
491
|
+
raise ImproperConfigurationError(msg) from self._pg_textsearch_probe_error
|
|
492
|
+
|
|
474
493
|
async def _close_pool(self) -> None:
|
|
475
494
|
"""Close the actual async connection pool and cleanup connectors."""
|
|
476
495
|
if self.connection_instance:
|
|
@@ -1240,6 +1240,8 @@ class PsycopgAsyncADKMemoryStore(BaseAsyncADKMemoryStore["PsycopgAsyncConfig"]):
|
|
|
1240
1240
|
return
|
|
1241
1241
|
|
|
1242
1242
|
async with self._config.provide_session() as driver:
|
|
1243
|
+
if self._enable_bm25:
|
|
1244
|
+
self._config._ensure_pg_textsearch_available()
|
|
1243
1245
|
await driver.execute_script(await self._memory_table_ddl())
|
|
1244
1246
|
|
|
1245
1247
|
async def insert_memory_entries(self, entries: "list[StoredMemory]", owner_id: "object | None" = None) -> int:
|
|
@@ -1256,10 +1258,10 @@ class PsycopgAsyncADKMemoryStore(BaseAsyncADKMemoryStore["PsycopgAsyncConfig"]):
|
|
|
1256
1258
|
query = pg_sql.SQL("""
|
|
1257
1259
|
INSERT INTO {table} (
|
|
1258
1260
|
id, session_id, app_name, user_id, scope, event_id, author,
|
|
1259
|
-
{owner_id_col}, timestamp, content_json, content_text,
|
|
1261
|
+
{owner_id_col}, timestamp, embedding, content_json, content_text,
|
|
1260
1262
|
metadata_json, inserted_at
|
|
1261
1263
|
) VALUES (
|
|
1262
|
-
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s
|
|
1264
|
+
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s::float8[]::vector, %s, %s, %s, %s
|
|
1263
1265
|
)
|
|
1264
1266
|
ON CONFLICT (event_id) DO NOTHING
|
|
1265
1267
|
""").format(
|
|
@@ -1269,9 +1271,9 @@ class PsycopgAsyncADKMemoryStore(BaseAsyncADKMemoryStore["PsycopgAsyncConfig"]):
|
|
|
1269
1271
|
query = pg_sql.SQL("""
|
|
1270
1272
|
INSERT INTO {table} (
|
|
1271
1273
|
id, session_id, app_name, user_id, scope, event_id, author,
|
|
1272
|
-
timestamp, content_json, content_text, metadata_json, inserted_at
|
|
1274
|
+
timestamp, embedding, content_json, content_text, metadata_json, inserted_at
|
|
1273
1275
|
) VALUES (
|
|
1274
|
-
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s
|
|
1276
|
+
%s, %s, %s, %s, %s, %s, %s, %s, %s::float8[]::vector, %s, %s, %s, %s
|
|
1275
1277
|
)
|
|
1276
1278
|
ON CONFLICT (event_id) DO NOTHING
|
|
1277
1279
|
""").format(table=pg_sql.Identifier(self._memory_table))
|
|
@@ -1395,7 +1397,7 @@ class PsycopgAsyncADKMemoryStore(BaseAsyncADKMemoryStore["PsycopgAsyncConfig"]):
|
|
|
1395
1397
|
sql = pg_sql.SQL(
|
|
1396
1398
|
"""
|
|
1397
1399
|
WITH vector_matches AS (
|
|
1398
|
-
SELECT id, RANK() OVER (ORDER BY embedding <=> %s) AS rank_vec
|
|
1400
|
+
SELECT id, RANK() OVER (ORDER BY embedding <=> %s::float8[]::vector) AS rank_vec
|
|
1399
1401
|
FROM {table}
|
|
1400
1402
|
WHERE {where_scope} AND embedding IS NOT NULL
|
|
1401
1403
|
LIMIT %s
|
|
@@ -1417,6 +1419,7 @@ class PsycopgAsyncADKMemoryStore(BaseAsyncADKMemoryStore["PsycopgAsyncConfig"]):
|
|
|
1417
1419
|
).format(table=pg_sql.Identifier(self._memory_table), where_scope=where_scope)
|
|
1418
1420
|
params = (list(embedding), *scope_params, candidate_limit, query, *scope_params, candidate_limit, limit)
|
|
1419
1421
|
async with self._config.provide_connection() as conn, conn.cursor(row_factory=dict_row) as cur:
|
|
1422
|
+
self._config._ensure_pg_textsearch_available()
|
|
1420
1423
|
await cur.execute(sql, params)
|
|
1421
1424
|
rows = await cur.fetchall()
|
|
1422
1425
|
return _rows_to_records(rows)
|
|
@@ -1434,7 +1437,7 @@ class PsycopgAsyncADKMemoryStore(BaseAsyncADKMemoryStore["PsycopgAsyncConfig"]):
|
|
|
1434
1437
|
"""
|
|
1435
1438
|
SELECT * FROM {table}
|
|
1436
1439
|
WHERE {where_scope} AND embedding IS NOT NULL
|
|
1437
|
-
ORDER BY embedding <=> %s ASC, timestamp DESC
|
|
1440
|
+
ORDER BY embedding <=> %s::float8[]::vector ASC, timestamp DESC
|
|
1438
1441
|
LIMIT %s
|
|
1439
1442
|
"""
|
|
1440
1443
|
).format(table=pg_sql.Identifier(self._memory_table), where_scope=where_scope)
|
|
@@ -1504,6 +1507,8 @@ class PsycopgSyncADKMemoryStore(BaseSyncADKMemoryStore["PsycopgSyncConfig"]):
|
|
|
1504
1507
|
return
|
|
1505
1508
|
|
|
1506
1509
|
with self._config.provide_session() as driver:
|
|
1510
|
+
if self._enable_bm25:
|
|
1511
|
+
self._config._ensure_pg_textsearch_available()
|
|
1507
1512
|
driver.execute_script(self._memory_table_ddl())
|
|
1508
1513
|
|
|
1509
1514
|
def insert_memory_entries(self, entries: "list[StoredMemory]", owner_id: "object | None" = None) -> int:
|
|
@@ -1520,10 +1525,10 @@ class PsycopgSyncADKMemoryStore(BaseSyncADKMemoryStore["PsycopgSyncConfig"]):
|
|
|
1520
1525
|
query = pg_sql.SQL("""
|
|
1521
1526
|
INSERT INTO {table} (
|
|
1522
1527
|
id, session_id, app_name, user_id, scope, event_id, author,
|
|
1523
|
-
{owner_id_col}, timestamp, content_json, content_text,
|
|
1528
|
+
{owner_id_col}, timestamp, embedding, content_json, content_text,
|
|
1524
1529
|
metadata_json, inserted_at
|
|
1525
1530
|
) VALUES (
|
|
1526
|
-
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s
|
|
1531
|
+
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s::float8[]::vector, %s, %s, %s, %s
|
|
1527
1532
|
)
|
|
1528
1533
|
ON CONFLICT (event_id) DO NOTHING
|
|
1529
1534
|
""").format(
|
|
@@ -1533,9 +1538,9 @@ class PsycopgSyncADKMemoryStore(BaseSyncADKMemoryStore["PsycopgSyncConfig"]):
|
|
|
1533
1538
|
query = pg_sql.SQL("""
|
|
1534
1539
|
INSERT INTO {table} (
|
|
1535
1540
|
id, session_id, app_name, user_id, scope, event_id, author,
|
|
1536
|
-
timestamp, content_json, content_text, metadata_json, inserted_at
|
|
1541
|
+
timestamp, embedding, content_json, content_text, metadata_json, inserted_at
|
|
1537
1542
|
) VALUES (
|
|
1538
|
-
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s
|
|
1543
|
+
%s, %s, %s, %s, %s, %s, %s, %s, %s::float8[]::vector, %s, %s, %s, %s
|
|
1539
1544
|
)
|
|
1540
1545
|
ON CONFLICT (event_id) DO NOTHING
|
|
1541
1546
|
""").format(table=pg_sql.Identifier(self._memory_table))
|
|
@@ -1656,7 +1661,7 @@ class PsycopgSyncADKMemoryStore(BaseSyncADKMemoryStore["PsycopgSyncConfig"]):
|
|
|
1656
1661
|
sql = pg_sql.SQL(
|
|
1657
1662
|
"""
|
|
1658
1663
|
WITH vector_matches AS (
|
|
1659
|
-
SELECT id, RANK() OVER (ORDER BY embedding <=> %s) AS rank_vec
|
|
1664
|
+
SELECT id, RANK() OVER (ORDER BY embedding <=> %s::float8[]::vector) AS rank_vec
|
|
1660
1665
|
FROM {table}
|
|
1661
1666
|
WHERE {where_scope} AND embedding IS NOT NULL
|
|
1662
1667
|
LIMIT %s
|
|
@@ -1678,6 +1683,7 @@ class PsycopgSyncADKMemoryStore(BaseSyncADKMemoryStore["PsycopgSyncConfig"]):
|
|
|
1678
1683
|
).format(table=pg_sql.Identifier(self._memory_table), where_scope=where_scope)
|
|
1679
1684
|
params = (list(embedding), *scope_params, candidate_limit, query, *scope_params, candidate_limit, limit)
|
|
1680
1685
|
with self._config.provide_connection() as conn, conn.cursor(row_factory=dict_row) as cur:
|
|
1686
|
+
self._config._ensure_pg_textsearch_available()
|
|
1681
1687
|
cur.execute(sql, params)
|
|
1682
1688
|
rows = cur.fetchall()
|
|
1683
1689
|
return _rows_to_records(rows)
|
|
@@ -1695,7 +1701,7 @@ class PsycopgSyncADKMemoryStore(BaseSyncADKMemoryStore["PsycopgSyncConfig"]):
|
|
|
1695
1701
|
"""
|
|
1696
1702
|
SELECT * FROM {table}
|
|
1697
1703
|
WHERE {where_scope} AND embedding IS NOT NULL
|
|
1698
|
-
ORDER BY embedding <=> %s ASC, timestamp DESC
|
|
1704
|
+
ORDER BY embedding <=> %s::float8[]::vector ASC, timestamp DESC
|
|
1699
1705
|
LIMIT %s
|
|
1700
1706
|
"""
|
|
1701
1707
|
).format(table=pg_sql.Identifier(self._memory_table), where_scope=where_scope)
|
|
@@ -1760,6 +1766,7 @@ def _build_insert_params(entry: "StoredMemory") -> "tuple[object, ...]":
|
|
|
1760
1766
|
entry["event_id"],
|
|
1761
1767
|
entry["author"],
|
|
1762
1768
|
entry["timestamp"],
|
|
1769
|
+
entry.get("embedding"),
|
|
1763
1770
|
Jsonb(entry["content_json"]),
|
|
1764
1771
|
entry["content_text"],
|
|
1765
1772
|
Jsonb(entry["metadata_json"]) if entry["metadata_json"] is not None else None,
|
|
@@ -1778,6 +1785,7 @@ def _build_insert_params_with_owner(entry: "StoredMemory", owner_id: "object | N
|
|
|
1778
1785
|
entry["author"],
|
|
1779
1786
|
owner_id,
|
|
1780
1787
|
entry["timestamp"],
|
|
1788
|
+
entry.get("embedding"),
|
|
1781
1789
|
Jsonb(entry["content_json"]),
|
|
1782
1790
|
entry["content_text"],
|
|
1783
1791
|
Jsonb(entry["metadata_json"]) if entry["metadata_json"] is not None else None,
|
|
@@ -1868,7 +1876,7 @@ def _postgres_memory_indexes(
|
|
|
1868
1876
|
|
|
1869
1877
|
if enable_bm25:
|
|
1870
1878
|
indexes.append(
|
|
1871
|
-
f"CREATE INDEX IF NOT EXISTS idx_{memory_table}_bm25 ON {memory_table} USING bm25 (content_text);"
|
|
1879
|
+
f"CREATE INDEX IF NOT EXISTS idx_{memory_table}_bm25 ON {memory_table} USING bm25 (content_text) WITH (text_config='english');"
|
|
1872
1880
|
)
|
|
1873
1881
|
|
|
1874
1882
|
if vector_index_type == "scann":
|
|
@@ -312,6 +312,8 @@ class PsycopgSyncConfig(SyncDatabaseConfig[PsycopgSyncConnection, ConnectionPool
|
|
|
312
312
|
features_dict.setdefault("alloydb_ip_type", "PRIVATE")
|
|
313
313
|
self._pgvector_available: bool | None = None
|
|
314
314
|
self._paradedb_available: bool | None = None
|
|
315
|
+
self._pg_textsearch_available: bool | None = None
|
|
316
|
+
self._pg_textsearch_probe_error: Exception | None = None
|
|
315
317
|
self._alloydb_connector: Any | None = None
|
|
316
318
|
|
|
317
319
|
super().__init__(
|
|
@@ -428,6 +430,14 @@ class PsycopgSyncConfig(SyncDatabaseConfig[PsycopgSyncConnection, ConnectionPool
|
|
|
428
430
|
if self._pgvector_available is None:
|
|
429
431
|
detected_extensions: set[str] = set()
|
|
430
432
|
extensions = build_postgres_extension_probe_names(self.driver_features)
|
|
433
|
+
adk_config = self.extension_config.get("adk", {})
|
|
434
|
+
bm25_enabled = bool(
|
|
435
|
+
isinstance(adk_config, dict)
|
|
436
|
+
and adk_config.get("enable_memory", True)
|
|
437
|
+
and adk_config.get("enable_bm25", False)
|
|
438
|
+
)
|
|
439
|
+
if bm25_enabled:
|
|
440
|
+
extensions.append("pg_textsearch")
|
|
431
441
|
if extensions:
|
|
432
442
|
try:
|
|
433
443
|
cursor = conn.execute(
|
|
@@ -435,11 +445,14 @@ class PsycopgSyncConfig(SyncDatabaseConfig[PsycopgSyncConnection, ConnectionPool
|
|
|
435
445
|
)
|
|
436
446
|
results = cursor.fetchall()
|
|
437
447
|
detected_extensions = {r[0] for r in results} # type: ignore[index]
|
|
438
|
-
except Exception:
|
|
448
|
+
except Exception as exc:
|
|
439
449
|
detected_extensions = set()
|
|
450
|
+
if bm25_enabled:
|
|
451
|
+
self._pg_textsearch_probe_error = exc
|
|
440
452
|
self.statement_config, self._pgvector_available, self._paradedb_available = (
|
|
441
453
|
resolve_postgres_extension_state(self.statement_config, self.driver_features, detected_extensions)
|
|
442
454
|
)
|
|
455
|
+
self._pg_textsearch_available = "pg_textsearch" in detected_extensions if bm25_enabled else False
|
|
443
456
|
|
|
444
457
|
if self._pgvector_available:
|
|
445
458
|
register_pgvector_sync(conn)
|
|
@@ -452,6 +465,12 @@ class PsycopgSyncConfig(SyncDatabaseConfig[PsycopgSyncConnection, ConnectionPool
|
|
|
452
465
|
if self._user_connection_hook is not None:
|
|
453
466
|
self._user_connection_hook(conn)
|
|
454
467
|
|
|
468
|
+
def _ensure_pg_textsearch_available(self) -> None:
|
|
469
|
+
if self._pg_textsearch_available:
|
|
470
|
+
return
|
|
471
|
+
msg = "ADK memory enable_bm25 requires the pg_textsearch PostgreSQL extension"
|
|
472
|
+
raise ImproperConfigurationError(msg) from self._pg_textsearch_probe_error
|
|
473
|
+
|
|
455
474
|
def _close_pool(self) -> None:
|
|
456
475
|
"""Close the actual connection pool and cleanup connectors."""
|
|
457
476
|
try:
|
|
@@ -638,6 +657,8 @@ class PsycopgAsyncConfig(AsyncDatabaseConfig[PsycopgAsyncConnection, AsyncConnec
|
|
|
638
657
|
)
|
|
639
658
|
self._pgvector_available: bool | None = None
|
|
640
659
|
self._paradedb_available: bool | None = None
|
|
660
|
+
self._pg_textsearch_available: bool | None = None
|
|
661
|
+
self._pg_textsearch_probe_error: Exception | None = None
|
|
641
662
|
|
|
642
663
|
super().__init__(
|
|
643
664
|
connection_config=connection_config,
|
|
@@ -700,6 +721,14 @@ class PsycopgAsyncConfig(AsyncDatabaseConfig[PsycopgAsyncConnection, AsyncConnec
|
|
|
700
721
|
if self._pgvector_available is None:
|
|
701
722
|
detected_extensions: set[str] = set()
|
|
702
723
|
extensions = build_postgres_extension_probe_names(self.driver_features)
|
|
724
|
+
adk_config = self.extension_config.get("adk", {})
|
|
725
|
+
bm25_enabled = bool(
|
|
726
|
+
isinstance(adk_config, dict)
|
|
727
|
+
and adk_config.get("enable_memory", True)
|
|
728
|
+
and adk_config.get("enable_bm25", False)
|
|
729
|
+
)
|
|
730
|
+
if bm25_enabled:
|
|
731
|
+
extensions.append("pg_textsearch")
|
|
703
732
|
if extensions:
|
|
704
733
|
try:
|
|
705
734
|
cursor = await conn.execute(
|
|
@@ -707,11 +736,14 @@ class PsycopgAsyncConfig(AsyncDatabaseConfig[PsycopgAsyncConnection, AsyncConnec
|
|
|
707
736
|
)
|
|
708
737
|
results = await cursor.fetchall()
|
|
709
738
|
detected_extensions = {r[0] for r in results} # type: ignore[index]
|
|
710
|
-
except Exception:
|
|
739
|
+
except Exception as exc:
|
|
711
740
|
detected_extensions = set()
|
|
741
|
+
if bm25_enabled:
|
|
742
|
+
self._pg_textsearch_probe_error = exc
|
|
712
743
|
self.statement_config, self._pgvector_available, self._paradedb_available = (
|
|
713
744
|
resolve_postgres_extension_state(self.statement_config, self.driver_features, detected_extensions)
|
|
714
745
|
)
|
|
746
|
+
self._pg_textsearch_available = "pg_textsearch" in detected_extensions if bm25_enabled else False
|
|
715
747
|
|
|
716
748
|
if self._pgvector_available:
|
|
717
749
|
await register_pgvector_async(conn)
|
|
@@ -724,6 +756,12 @@ class PsycopgAsyncConfig(AsyncDatabaseConfig[PsycopgAsyncConnection, AsyncConnec
|
|
|
724
756
|
if self._user_connection_hook is not None:
|
|
725
757
|
await self._user_connection_hook(conn)
|
|
726
758
|
|
|
759
|
+
def _ensure_pg_textsearch_available(self) -> None:
|
|
760
|
+
if self._pg_textsearch_available:
|
|
761
|
+
return
|
|
762
|
+
msg = "ADK memory enable_bm25 requires the pg_textsearch PostgreSQL extension"
|
|
763
|
+
raise ImproperConfigurationError(msg) from self._pg_textsearch_probe_error
|
|
764
|
+
|
|
727
765
|
async def _close_pool(self) -> None:
|
|
728
766
|
"""Close the actual async connection pool."""
|
|
729
767
|
if not self.connection_instance:
|
sqlspec/builder/_ddl.py
CHANGED
|
@@ -688,7 +688,7 @@ class _SingleObjectDropBuilder(DDLBuilder, _IfExistsDDLMixin, _CascadeRestrictDD
|
|
|
688
688
|
self._require(self._name, f"{self._object_label} name must be set for DROP {self._drop_kind}.")
|
|
689
689
|
return exp.Drop(
|
|
690
690
|
kind=self._drop_kind,
|
|
691
|
-
|
|
691
|
+
tables=[self._build_drop_this()],
|
|
692
692
|
exists=self._if_exists,
|
|
693
693
|
cascade=self._cascade,
|
|
694
694
|
**self._drop_expression_args(),
|
|
@@ -1464,10 +1464,10 @@ class AlterTable(DDLBuilder, _IfExistsDDLMixin):
|
|
|
1464
1464
|
return build_column_expression(op.column_definition)
|
|
1465
1465
|
|
|
1466
1466
|
if op_type == "DROP COLUMN":
|
|
1467
|
-
return exp.Drop(
|
|
1467
|
+
return exp.Drop(tables=[exp.to_identifier(op.column_name)], kind="COLUMN", exists=True)
|
|
1468
1468
|
|
|
1469
1469
|
if op_type == "DROP COLUMN CASCADE":
|
|
1470
|
-
return exp.Drop(
|
|
1470
|
+
return exp.Drop(tables=[exp.to_identifier(op.column_name)], kind="COLUMN", cascade=True, exists=True)
|
|
1471
1471
|
|
|
1472
1472
|
if op_type == "ALTER COLUMN TYPE":
|
|
1473
1473
|
if not op.new_type:
|
|
@@ -1488,10 +1488,12 @@ class AlterTable(DDLBuilder, _IfExistsDDLMixin):
|
|
|
1488
1488
|
return exp.AddConstraint(expressions=[constraint_expr])
|
|
1489
1489
|
|
|
1490
1490
|
if op_type == "DROP CONSTRAINT":
|
|
1491
|
-
return exp.Drop(
|
|
1491
|
+
return exp.Drop(tables=[exp.to_identifier(op.constraint_name)], kind="CONSTRAINT", exists=True)
|
|
1492
1492
|
|
|
1493
1493
|
if op_type == "DROP CONSTRAINT CASCADE":
|
|
1494
|
-
return exp.Drop(
|
|
1494
|
+
return exp.Drop(
|
|
1495
|
+
tables=[exp.to_identifier(op.constraint_name)], kind="CONSTRAINT", cascade=True, exists=True
|
|
1496
|
+
)
|
|
1495
1497
|
|
|
1496
1498
|
if op_type == "ALTER COLUMN SET NOT NULL":
|
|
1497
1499
|
return exp.AlterColumn(this=exp.to_identifier(op.column_name), allow_null=False)
|
sqlspec/config.py
CHANGED
|
@@ -739,7 +739,7 @@ class ADKConfig(TypedDict):
|
|
|
739
739
|
"""Dimensionality of embedding vectors (e.g. 768 for gemini-embedding-001 with MRL). Default: 768."""
|
|
740
740
|
|
|
741
741
|
enable_bm25: NotRequired[bool]
|
|
742
|
-
"""Enable native
|
|
742
|
+
"""Enable native BM25 full-text indexing. Requires the pg_textsearch extension. Default: False."""
|
|
743
743
|
|
|
744
744
|
scann_num_leaves: NotRequired[int]
|
|
745
745
|
"""Number of partition leaves (clusters) for ScaNN tree quantization. Default: 100."""
|
|
@@ -1524,8 +1524,8 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
|
|
|
1524
1524
|
self.extension_config = extension_config or {}
|
|
1525
1525
|
self.migration_config = migration_config or {}
|
|
1526
1526
|
self._init_observability(observability_config)
|
|
1527
|
-
self._initialize_migration_components()
|
|
1528
1527
|
self.statement_config = statement_config or build_default_statement_config(default_dialect)
|
|
1528
|
+
self._initialize_migration_components()
|
|
1529
1529
|
self._storage_capabilities = None
|
|
1530
1530
|
self.driver_features = seed_runtime_driver_features(driver_features, self.storage_capabilities())
|
|
1531
1531
|
self._attach_lifecycle_hooks()
|
|
@@ -8,8 +8,8 @@ Creates the canonical ADK tables:
|
|
|
8
8
|
- adk_internal_metadata
|
|
9
9
|
- adk_memory (when memory is enabled)
|
|
10
10
|
|
|
11
|
-
On PostgreSQL the migration installs
|
|
12
|
-
memory statement that
|
|
11
|
+
On PostgreSQL the migration installs required extensions before the first
|
|
12
|
+
memory statement that uses them.
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
15
|
import inspect
|
|
@@ -38,9 +38,11 @@ __all__ = ("down", "up")
|
|
|
38
38
|
logger = get_logger("sqlspec.migrations.adk.create")
|
|
39
39
|
|
|
40
40
|
CREATE_VECTOR_EXTENSION = "CREATE EXTENSION IF NOT EXISTS vector"
|
|
41
|
+
CREATE_PG_TEXTSEARCH_EXTENSION = "CREATE EXTENSION IF NOT EXISTS pg_textsearch"
|
|
41
42
|
|
|
42
43
|
_POSTGRES_DIALECTS = frozenset({"postgres", "postgresql", "pgvector", "paradedb"})
|
|
43
44
|
_VECTOR_COLUMN_PATTERN = re.compile(r"\bVECTOR\s*\(", re.IGNORECASE)
|
|
45
|
+
_BM25_INDEX_PATTERN = re.compile(r"\bUSING\s+bm25\s*\(", re.IGNORECASE)
|
|
44
46
|
|
|
45
47
|
|
|
46
48
|
async def up(context: "MigrationContext | None" = None) -> "list[str]":
|
|
@@ -70,7 +72,7 @@ async def up(context: "MigrationContext | None" = None) -> "list[str]":
|
|
|
70
72
|
if inspect.isawaitable(memory_sql):
|
|
71
73
|
memory_sql = await memory_sql
|
|
72
74
|
memory_statements = list(memory_sql) if isinstance(memory_sql, list) else [memory_sql]
|
|
73
|
-
statements.extend(
|
|
75
|
+
statements.extend(_with_postgres_extensions(memory_statements, context))
|
|
74
76
|
log_with_context(
|
|
75
77
|
logger, logging.DEBUG, "adk.migration.create.memory.create", table_name=memory_store.memory_table
|
|
76
78
|
)
|
|
@@ -98,15 +100,24 @@ async def down(context: "MigrationContext | None" = None) -> "list[str]":
|
|
|
98
100
|
return statements
|
|
99
101
|
|
|
100
102
|
|
|
101
|
-
def
|
|
102
|
-
"""Prepend
|
|
103
|
+
def _with_postgres_extensions(statements: "list[str]", context: "MigrationContext") -> "list[str]":
|
|
104
|
+
"""Prepend required PostgreSQL extensions before their first use."""
|
|
103
105
|
dialect = (context.dialect or "").lower()
|
|
104
106
|
if dialect not in _POSTGRES_DIALECTS:
|
|
105
107
|
return statements
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
|
|
109
|
+
result: list[str] = []
|
|
110
|
+
vector_enabled = False
|
|
111
|
+
pg_textsearch_enabled = False
|
|
112
|
+
for statement in statements:
|
|
113
|
+
if not vector_enabled and _VECTOR_COLUMN_PATTERN.search(statement):
|
|
114
|
+
result.append(CREATE_VECTOR_EXTENSION)
|
|
115
|
+
vector_enabled = True
|
|
116
|
+
if not pg_textsearch_enabled and _BM25_INDEX_PATTERN.search(statement):
|
|
117
|
+
result.append(CREATE_PG_TEXTSEARCH_EXTENSION)
|
|
118
|
+
pg_textsearch_enabled = True
|
|
119
|
+
result.append(statement)
|
|
120
|
+
return result
|
|
110
121
|
|
|
111
122
|
|
|
112
123
|
def _raise_missing_config() -> NoReturn:
|
|
@@ -833,12 +833,21 @@ class SQLSpecPlugin(InitPluginProtocol, CLIPlugin):
|
|
|
833
833
|
Args:
|
|
834
834
|
name: A ``session_key``, ``connection_key``, or ``pool_key``.
|
|
835
835
|
|
|
836
|
+
Raises:
|
|
837
|
+
KeyError: If ``name`` is not a known dependency key.
|
|
838
|
+
|
|
836
839
|
Returns:
|
|
837
840
|
The matching plugin state.
|
|
838
841
|
"""
|
|
839
|
-
if
|
|
840
|
-
self.
|
|
841
|
-
|
|
842
|
+
if isinstance(name, str) and any(
|
|
843
|
+
name in {state.connection_key, state.pool_key, state.session_key} for state in self._plugin_configs
|
|
844
|
+
):
|
|
845
|
+
if any(state.annotation is None for state in self._plugin_configs):
|
|
846
|
+
self._raise_plugin_not_registered()
|
|
847
|
+
return self._get_plugin_state(name)
|
|
848
|
+
self._raise_config_not_found(name)
|
|
849
|
+
msg = "unreachable"
|
|
850
|
+
raise AssertionError(msg)
|
|
842
851
|
|
|
843
852
|
def _get_plugin_state(
|
|
844
853
|
self, key: "str | DatabaseConfigProtocol[Any, Any, Any] | type[DatabaseConfigProtocol[Any, Any, Any]]"
|
|
@@ -4,7 +4,7 @@ sqlspec/__metadata__.py,sha256=IUw6MCTy1oeUJ1jAVYbuJLkOWbiAWorZ5W-E-SAD9N4,395
|
|
|
4
4
|
sqlspec/_typing.py,sha256=OLBKW7FSh22fPAr4BiLmFBovxi0MSVvA-KJzWE7RDDE,21809
|
|
5
5
|
sqlspec/base.py,sha256=-yJlxdfDpZ-SHMTav87zqs39pu6zsKsLXBJYp8MsmPY,30257
|
|
6
6
|
sqlspec/cli.py,sha256=2cD6ZYoXGA5RyGD_KtIulfbSp3YtK3RNNW3pqEDZ0I8,42427
|
|
7
|
-
sqlspec/config.py,sha256=
|
|
7
|
+
sqlspec/config.py,sha256=m5MWkorlbju3AiQ1ruIvXcDv_dkqJgsBwzQ2IJEyURs,81601
|
|
8
8
|
sqlspec/exceptions.py,sha256=kbk9JjaWlBIQ6xeZIJHlhKMDd1RSOPSzqgAZ4dTk9xs,15128
|
|
9
9
|
sqlspec/loader.py,sha256=SMTEa6MFg6EqnKuENNQDOPizKGXD2YuaE4COjE_3MFk,36208
|
|
10
10
|
sqlspec/protocols.py,sha256=zfFH3w343I3qn11Fvo20jmghmTCd3GQWW-kpx8RQN9c,33942
|
|
@@ -66,24 +66,24 @@ sqlspec/adapters/arrow_odbc/litestar/__init__.py,sha256=8X-ptnPzniv1GvGOYSUHLKil
|
|
|
66
66
|
sqlspec/adapters/arrow_odbc/litestar/store.py,sha256=XJ_g9w3-pRdVK-eh8MBCkDbFe2gGZzdwt5mKzsBV01U,11508
|
|
67
67
|
sqlspec/adapters/asyncmy/__init__.py,sha256=EgFaxoi1bDhcJIo2ApXG2rsJ1q5ELvMv4PeV3A27OPA,671
|
|
68
68
|
sqlspec/adapters/asyncmy/_typing.py,sha256=B-sge2R-b8LwFUNfgtfHT68qMGOwcA2n6B7gppHY55Q,5215
|
|
69
|
-
sqlspec/adapters/asyncmy/config.py,sha256=
|
|
69
|
+
sqlspec/adapters/asyncmy/config.py,sha256=F2rY_QWIgKFJgTDHm2AhfAsfZpjGFJVbWoAdwgaJboc,16491
|
|
70
70
|
sqlspec/adapters/asyncmy/core.py,sha256=DD9cIVq79qaqnrdXyrsYZ5EEwIkj6TkqeUUmfkSawoA,23019
|
|
71
71
|
sqlspec/adapters/asyncmy/data_dictionary.py,sha256=8Xc9YhdS9JL2JpSscDiSha6q82sbKi7SwDGI2tyPx5k,14278
|
|
72
72
|
sqlspec/adapters/asyncmy/driver.py,sha256=nK6hL5DA7SFvD4NYagpmMCmXNHDfUs2kW599GwfVEho,18344
|
|
73
73
|
sqlspec/adapters/asyncmy/adk/__init__.py,sha256=jD7XeHf01jPsMigmHVHg2rh3Zs_41hzNf4ejzIOP6Fk,239
|
|
74
|
-
sqlspec/adapters/asyncmy/adk/store.py,sha256=
|
|
74
|
+
sqlspec/adapters/asyncmy/adk/store.py,sha256=0tS7lGJLB1cG7IsVZ1aXnbWvH6Op6w8lGjNWlMlILj0,38350
|
|
75
75
|
sqlspec/adapters/asyncmy/events/__init__.py,sha256=lbYNTyDvrtMm9Cg_IP4x-_4CymFl2SU-nkBjc7sz45k,159
|
|
76
76
|
sqlspec/adapters/asyncmy/events/store.py,sha256=zQMzTYuZkX1Tuw_jXnwLM19IPMgOeH90JQdAjX0VeUo,2687
|
|
77
77
|
sqlspec/adapters/asyncmy/litestar/__init__.py,sha256=VNBusWFPvw4BBLHi7gSSY3S94JxjZ7oJoAavTVvcZ28,143
|
|
78
|
-
sqlspec/adapters/asyncmy/litestar/store.py,sha256=
|
|
78
|
+
sqlspec/adapters/asyncmy/litestar/store.py,sha256=1xFCxR-8KXCRmzbNflxnTuuOkbwq-RZpq8vXg1kZ17g,10626
|
|
79
79
|
sqlspec/adapters/asyncpg/__init__.py,sha256=mgfrmVs5E1jnKUM76AosWJ2Lceuq0dRw-49xcgAxpxo,751
|
|
80
80
|
sqlspec/adapters/asyncpg/_typing.py,sha256=67ElS_NC8PAI8wMb7tY_-DXo_tdE_HSkexqsDVBJ73A,3727
|
|
81
|
-
sqlspec/adapters/asyncpg/config.py,sha256=
|
|
81
|
+
sqlspec/adapters/asyncpg/config.py,sha256=80IzVYLKkwcFWH9rhUp5lzzCSM44oLef8NKfGVxkyEQ,25868
|
|
82
82
|
sqlspec/adapters/asyncpg/core.py,sha256=r1oj6HFR3950GeHmA0PrsnvkgQ2iYNtc9BhTKX4imnI,19522
|
|
83
83
|
sqlspec/adapters/asyncpg/data_dictionary.py,sha256=Wdg-moMyVJHUUaIpuUhwCaFMN8pJmKiW5sTsQ6PDpck,17926
|
|
84
84
|
sqlspec/adapters/asyncpg/driver.py,sha256=xmXl2LH2MS44yUj9Thp1opjbNhDZR0Dj_aNYRiG-ICk,30903
|
|
85
85
|
sqlspec/adapters/asyncpg/adk/__init__.py,sha256=p1ZELfzC21x4zE9vl4How2_-UIdxkWt0HVhrISWl0iQ,213
|
|
86
|
-
sqlspec/adapters/asyncpg/adk/store.py,sha256
|
|
86
|
+
sqlspec/adapters/asyncpg/adk/store.py,sha256=-3-PuWfRPAA-SnSeyg7XTQCWQT5B5zzyr2e0IMsMiQ4,36947
|
|
87
87
|
sqlspec/adapters/asyncpg/events/__init__.py,sha256=YOlB9kRztWLqMeW87AGQKBTLIYNM2puuKy_EwWKvJX8,301
|
|
88
88
|
sqlspec/adapters/asyncpg/events/_hub.py,sha256=flKFiiSvpVT9sR11wA99X00mvmAE7dr5me3tCrQgt-M,9834
|
|
89
89
|
sqlspec/adapters/asyncpg/events/backend.py,sha256=fLC8XAJd6LLqjLOMch5PTiGUOrlSUVs8-jqrTZgtPRU,15493
|
|
@@ -204,13 +204,13 @@ sqlspec/adapters/psqlpy/litestar/__init__.py,sha256=ODTxzJFNmexprYuBZcCxQWsJXPuS
|
|
|
204
204
|
sqlspec/adapters/psqlpy/litestar/store.py,sha256=gjDTnxUCS4_79Q2dqtwxn9fXiJlCiA89REr2RkgUXrU,8779
|
|
205
205
|
sqlspec/adapters/psycopg/__init__.py,sha256=mYXt-Jl2BD35wnOIodPGFfYRKUQ6AT_X1qoUUhb5S4A,969
|
|
206
206
|
sqlspec/adapters/psycopg/_typing.py,sha256=eGbCUsktUgx7wC92poF8k2j-Fw5AYlJc5szmKvrJOLo,8103
|
|
207
|
-
sqlspec/adapters/psycopg/config.py,sha256=
|
|
207
|
+
sqlspec/adapters/psycopg/config.py,sha256=tlR1m3oxht4IaMycw5sFBaAW-w01oZ-YvuzbU3W1xnE,37145
|
|
208
208
|
sqlspec/adapters/psycopg/core.py,sha256=J5P-mE1Bv5t0411HJNLrWI9LWVVVUnxM1hrusN3wz9E,24902
|
|
209
209
|
sqlspec/adapters/psycopg/data_dictionary.py,sha256=xtEhbOk49iZgkncskH8tE0sX1-YfZxHgg08dB_ovheA,30658
|
|
210
210
|
sqlspec/adapters/psycopg/driver.py,sha256=FoZc_Z8aOmddmEPNtnINa45tNCoCVpA0v0sQ9LsB_WA,58156
|
|
211
211
|
sqlspec/adapters/psycopg/type_converter.py,sha256=C-ynmx47HvpBOd4UalspSEnFMeRE9kZBIkOdhtsz_X4,2980
|
|
212
212
|
sqlspec/adapters/psycopg/adk/__init__.py,sha256=WYeffXiBnWiCXLGKkP03zsWEz_BtfU8S79P2nd5ePXA,381
|
|
213
|
-
sqlspec/adapters/psycopg/adk/store.py,sha256=
|
|
213
|
+
sqlspec/adapters/psycopg/adk/store.py,sha256=VJWWc1yRiigdysto2IbB0zHPJuBSw2y-M7Bh6JDNq5c,81025
|
|
214
214
|
sqlspec/adapters/psycopg/events/__init__.py,sha256=bJTqdKRaUZeDqn13rIS4zPKVm79fbkoch-8dceYgVYc,623
|
|
215
215
|
sqlspec/adapters/psycopg/events/_hub.py,sha256=YssMbQ1_UCe4P_OhVF4wkYyXyeftBFegJ77sGWyL-yM,21051
|
|
216
216
|
sqlspec/adapters/psycopg/events/backend.py,sha256=c6RJGGPVl0QVxz5kZndjgzyu4kctrHxzlrJo1Gv6e6o,28692
|
|
@@ -274,7 +274,7 @@ sqlspec/adapters/sqlite/litestar/store.py,sha256=d8Uk2YdbbkpIWKhLmVWue16fXVRfALx
|
|
|
274
274
|
sqlspec/builder/__init__.py,sha256=S-yrPxGah-kKg0OtDE05qkB8nIRsVlNmtsP5dEchKW8,4380
|
|
275
275
|
sqlspec/builder/_base.py,sha256=JPhbA_NyHsvB1cCvkyX4qYmfYKIR5-Hb3Xt3h4y3ACA,39774
|
|
276
276
|
sqlspec/builder/_column.py,sha256=_Do3Xt7wkk2uEmdNKIIx3uMgEjdeXhGMmQbMbIefQ1Y,16312
|
|
277
|
-
sqlspec/builder/_ddl.py,sha256=
|
|
277
|
+
sqlspec/builder/_ddl.py,sha256=bNpLdHYo9z_N5U518dR2ua2Se8sFgD2pR8a8OAFQk_M,58106
|
|
278
278
|
sqlspec/builder/_delete.py,sha256=--KFsRs1XUA3TE1PZNd5YQgmyCJGaA4GvEGgiUho80U,2614
|
|
279
279
|
sqlspec/builder/_dml.py,sha256=1uQJ9jcXXHTQcfe00voNmEIxLvoaRAjZgScLZF_jO4w,15373
|
|
280
280
|
sqlspec/builder/_explain.py,sha256=S7wDHWeraZDft_hJZm6ajgJiwIzRo6E5-yIXThhTsH4,18813
|
|
@@ -556,7 +556,7 @@ sqlspec/extensions/adk/memory/_types.py,sha256=2WRAEmug7D0upyakhx5QpbgOEH2dMAoSX
|
|
|
556
556
|
sqlspec/extensions/adk/memory/converters.py,sha256=zxH4rY6dEsP0Hw05DjyA6Y3iUGBHl0N9vFLktOKeEo8,7930
|
|
557
557
|
sqlspec/extensions/adk/memory/service.py,sha256=QvbRIJlKFnd8MqS6Clq1zvLswFlg39sjQ75TyladkJM,11429
|
|
558
558
|
sqlspec/extensions/adk/memory/store.py,sha256=m86r-gZf8A7Y6XRjr5llGh0Fcwh8_22UDGH6fsCdbrE,16135
|
|
559
|
-
sqlspec/extensions/adk/migrations/0001_create_adk_tables.py,sha256=
|
|
559
|
+
sqlspec/extensions/adk/migrations/0001_create_adk_tables.py,sha256=EBC8fxJJlC320r6fiOrVQ9o2x-zrZFlcjgZz3PKiEPk,6760
|
|
560
560
|
sqlspec/extensions/adk/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
561
561
|
sqlspec/extensions/events/__init__.py,sha256=ZD77SUD7t_g4zpI3RmeL2SGT9cwtx6sDkhmdcIbUoWM,1808
|
|
562
562
|
sqlspec/extensions/events/_buffer.py,sha256=H7Lj4g_AafICFptFVSGquapH5uWrENk27f6wCB559Y0,1404
|
|
@@ -583,7 +583,7 @@ sqlspec/extensions/litestar/channels.py,sha256=W-EKVEmXOPrdrcsNh1a-FzIWGcdEE6V24
|
|
|
583
583
|
sqlspec/extensions/litestar/cli.py,sha256=6ZHIWNT0RPzgr3LOKVAIEk9hUcyJTMUKgnpjkBrdliA,3476
|
|
584
584
|
sqlspec/extensions/litestar/config.py,sha256=EvHRJjAdGuJkbRj0Ke7QsU6eXef_okLLPm0-atD4uXM,3597
|
|
585
585
|
sqlspec/extensions/litestar/handlers.py,sha256=VTtBoCfl8zxtEe9N1_aZrFA4ILrEbP_2FjFuFg-9FF4,11162
|
|
586
|
-
sqlspec/extensions/litestar/plugin.py,sha256=
|
|
586
|
+
sqlspec/extensions/litestar/plugin.py,sha256=t_e1MHDOx-8Hzn9s7Ua7elcWh68Ove8GVED0xaN6a_8,46506
|
|
587
587
|
sqlspec/extensions/litestar/providers.py,sha256=ofpZf9EJbXVmVyqKkAM2ef1HM_4bEzpAT7EvK1Ejf7k,41361
|
|
588
588
|
sqlspec/extensions/litestar/store.py,sha256=4b9QC4s7R7Xh_6WDbrGKyES__XZuIhtpWw_6uUTDHBg,9996
|
|
589
589
|
sqlspec/extensions/litestar/migrations/0001_create_session_table.py,sha256=60HehSre1tXoHaOBx_75Hha-7smWP61RYrRVBYnIo8w,4206
|
|
@@ -665,8 +665,8 @@ sqlspec/utils/serializers/__init__.py,sha256=X99t8YMHVGmKwrqPxumnSXu4JMJL8SpKoU7
|
|
|
665
665
|
sqlspec/utils/serializers/_json.py,sha256=5PBan5kHoDAGqbOqT33SdEK17VZzNjzZKneWI_BnDzY,18136
|
|
666
666
|
sqlspec/utils/serializers/_numpy.py,sha256=_LllCtVn_gyLrRG2naHM7Unjtpot86BPTvGPlZuAGRw,1742
|
|
667
667
|
sqlspec/utils/serializers/_schema.py,sha256=kN8lW8GJa08yMi_qN_x8A7XpO7V6aAaoYqKq72rxaCk,11416
|
|
668
|
-
sqlspec-0.62.
|
|
669
|
-
sqlspec-0.62.
|
|
670
|
-
sqlspec-0.62.
|
|
671
|
-
sqlspec-0.62.
|
|
672
|
-
sqlspec-0.62.
|
|
668
|
+
sqlspec-0.62.2.dist-info/METADATA,sha256=pdDXwLK4BTqODd8EBgo8AAaRs7cRPDUh4sRvnZYACyY,9066
|
|
669
|
+
sqlspec-0.62.2.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
670
|
+
sqlspec-0.62.2.dist-info/entry_points.txt,sha256=T_1g2gTpkUsl6YC-KSCoNS5r7CPG2kn6wyp1WyMvpqU,404
|
|
671
|
+
sqlspec-0.62.2.dist-info/licenses/LICENSE,sha256=MdujfZ6l5HuLz4mElxlu049itenOR3gnhN1_Nd3nVcM,1078
|
|
672
|
+
sqlspec-0.62.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|