amfs-adapter-postgres 0.2.41__tar.gz → 0.2.43__tar.gz
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.
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/PKG-INFO +2 -2
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/pyproject.toml +2 -2
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/adapter.py +152 -4
- amfs_adapter_postgres-0.2.43/src/amfs_postgres/migrations/014_outcome_covariates.sql +20 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/.gitignore +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/__init__.py +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/_fts.py +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/async_adapter.py +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/evidence_sql.py +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/knn.py +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/migrations/001_initial.sql +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/migrations/002_artifact_refs.sql +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/migrations/002_search_indexes.sql +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/migrations/003_knowledge_graph.sql +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/migrations/004_agent_groups.sql +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/migrations/005_configurable_embedding_dim.sql +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/migrations/006_is_artifact.sql +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/migrations/006_outcome_confidence_semantics.sql +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/migrations/007_outcome_propagation_row_copy.sql +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/migrations/008_outcome_evidence.sql +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/migrations/009_action_priors.sql +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/migrations/010_local_evidence.sql +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/migrations/011_outcome_task_text.sql +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/migrations/012_evidence_from_model.sql +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/migrations/013_outcome_verified_by_backfill.sql +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/retention.py +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/schema.sql +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/tenant_context.py +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/tenant_gucs.py +0 -0
- {amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/trace_partitions.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: amfs-adapter-postgres
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.43
|
|
4
4
|
Summary: AMFS Postgres adapter with back-propagation triggers
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Requires-Python: >=3.11
|
|
7
|
-
Requires-Dist: amfs-core>=0.3.
|
|
7
|
+
Requires-Dist: amfs-core>=0.3.54
|
|
8
8
|
Requires-Dist: psycopg-pool>=3.1
|
|
9
9
|
Requires-Dist: psycopg[binary]<4,>=3.1
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "amfs-adapter-postgres"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.43"
|
|
4
4
|
description = "AMFS Postgres adapter with back-propagation triggers"
|
|
5
5
|
requires-python = ">=3.11"
|
|
6
6
|
license = "Apache-2.0"
|
|
7
7
|
dependencies = [
|
|
8
8
|
# 0.3.14 adds the capture fields this adapter now persists and selects back,
|
|
9
9
|
# tool_calls among them.
|
|
10
|
-
"amfs-core>=0.3.
|
|
10
|
+
"amfs-core>=0.3.54",
|
|
11
11
|
"psycopg[binary]>=3.1,<4",
|
|
12
12
|
"psycopg-pool>=3.1",
|
|
13
13
|
]
|
|
@@ -34,7 +34,7 @@ from amfs_core.exclusions import (
|
|
|
34
34
|
AGENT_ID_NOT_EXCLUDED_SQL,
|
|
35
35
|
ENTITY_PATH_NOT_EXCLUDED_SQL,
|
|
36
36
|
)
|
|
37
|
-
from amfs_core.actions import entity_paths_of, recorded_environment
|
|
37
|
+
from amfs_core.actions import entity_paths_of, recorded_covariates, recorded_environment
|
|
38
38
|
from amfs_core.evidence import cited_entries, outcome_model, outcome_read_keys, outcome_verified_by
|
|
39
39
|
from amfs_core.models import (
|
|
40
40
|
OUTCOME_MULTIPLIERS,
|
|
@@ -183,6 +183,45 @@ def _paginate_sql(
|
|
|
183
183
|
return query, params
|
|
184
184
|
|
|
185
185
|
|
|
186
|
+
def priority_score_sql(now: datetime, config: Any | None = None) -> tuple[str, list[Any]]:
|
|
187
|
+
"""``amfs_core.tiering.PriorityScorer.score`` as a SQL expression.
|
|
188
|
+
|
|
189
|
+
The tiers pages rank every current entry in the account by this score and
|
|
190
|
+
take the top 50 as Hot and the next 200 as Warm. Scoring in Python meant
|
|
191
|
+
loading the whole namespace first; on a 420K-entry account the two
|
|
192
|
+
requests the page makes together took an 8 GiB instance down. The
|
|
193
|
+
expression below is the same formula over the same columns, so the
|
|
194
|
+
database can order by it and hand back one page::
|
|
195
|
+
|
|
196
|
+
(alpha * importance + beta * recency) * freq_boost * time_decay
|
|
197
|
+
|
|
198
|
+
with ``importance = importance_score or confidence`` clamped to [0, 1],
|
|
199
|
+
``recency = exp(-lambda * age_days)``, ``freq_boost = max(1, ln(1 +
|
|
200
|
+
recall_count))`` and ``time_decay = exp(-lambda * age_days / freq_boost)``.
|
|
201
|
+
``importance_score`` of 0 falls through to confidence exactly as the
|
|
202
|
+
Python ``or`` does. Returns the expression and its parameters in placeholder
|
|
203
|
+
order: alpha, beta, lambda, *now*, lambda, *now*.
|
|
204
|
+
"""
|
|
205
|
+
if config is None:
|
|
206
|
+
from amfs_core.models import TierConfig
|
|
207
|
+
|
|
208
|
+
config = TierConfig()
|
|
209
|
+
age_days = "GREATEST(0.0, EXTRACT(EPOCH FROM (%s - written_at)) / 86400.0)"
|
|
210
|
+
importance = (
|
|
211
|
+
"LEAST(1.0, GREATEST(0.0, COALESCE(NULLIF(importance_score, 0), confidence)::float8))"
|
|
212
|
+
)
|
|
213
|
+
freq_boost = "GREATEST(1.0, LN(1.0 + COALESCE(recall_count, 0)))"
|
|
214
|
+
expr = (
|
|
215
|
+
f"((%s * {importance} + %s * EXP(-%s * {age_days}))"
|
|
216
|
+
f" * {freq_boost}"
|
|
217
|
+
f" * EXP(-%s * {age_days} / {freq_boost}))"
|
|
218
|
+
)
|
|
219
|
+
# The age expression appears twice, each with its own ``now``.
|
|
220
|
+
lam = float(config.decay_lambda)
|
|
221
|
+
params: list[Any] = [float(config.alpha), float(config.beta), lam, now, lam, now]
|
|
222
|
+
return expr, params
|
|
223
|
+
|
|
224
|
+
|
|
186
225
|
def list_conditions(
|
|
187
226
|
namespace: str,
|
|
188
227
|
entity_path: str | None,
|
|
@@ -274,6 +313,10 @@ _LOCAL_EVIDENCE_SQL = (
|
|
|
274
313
|
_OUTCOME_TASK_TEXT_SQL = (
|
|
275
314
|
Path(__file__).parent / "migrations" / "011_outcome_task_text.sql"
|
|
276
315
|
).read_text(encoding="utf-8")
|
|
316
|
+
#: Migration 014 — the covariates of the task on the outcome row.
|
|
317
|
+
_OUTCOME_COVARIATES_SQL = (
|
|
318
|
+
Path(__file__).parent / "migrations" / "014_outcome_covariates.sql"
|
|
319
|
+
).read_text(encoding="utf-8")
|
|
277
320
|
#: Migration 012 — the evidence functions rendered from ``amfs_core.evidence``
|
|
278
321
|
#: (``evidence_sql.render_evidence_sql``), replacing the hand-written bodies
|
|
279
322
|
#: of 008/009 with the same arithmetic read off the Python model. Applied
|
|
@@ -825,6 +868,7 @@ class PostgresAdapter(AdapterABC):
|
|
|
825
868
|
self._has_outcome_embedding_col = False
|
|
826
869
|
self._has_outcome_env_col = False
|
|
827
870
|
self._has_task_text_col = False
|
|
871
|
+
self._has_covariates_col = False
|
|
828
872
|
self._has_verified_by_col = False
|
|
829
873
|
self._pgvector_version: tuple[int, ...] | None = None
|
|
830
874
|
# When an embedder is provided, embeddings are computed at write time and
|
|
@@ -1336,6 +1380,12 @@ class PostgresAdapter(AdapterABC):
|
|
|
1336
1380
|
ALTER TABLE amfs_outcomes
|
|
1337
1381
|
ADD COLUMN IF NOT EXISTS environment JSONB
|
|
1338
1382
|
""")
|
|
1383
|
+
# The covariates of the task — the run's declared attributes other
|
|
1384
|
+
# than its environment and situation (the customer's plan, the app
|
|
1385
|
+
# version a lookup showed) — so a contested situation's record can be
|
|
1386
|
+
# split by what separates the runs the old action still wins from the
|
|
1387
|
+
# ones it lost (amfs_core.actions.split_contested). See migration 014.
|
|
1388
|
+
cur.execute(_OUTCOME_COVARIATES_SQL)
|
|
1339
1389
|
# Query-conditioned evidence: see migration 010.
|
|
1340
1390
|
cur.execute(_LOCAL_EVIDENCE_SQL)
|
|
1341
1391
|
# The task text on outcomes: see migration 011.
|
|
@@ -1806,7 +1856,7 @@ class PostgresAdapter(AdapterABC):
|
|
|
1806
1856
|
WHERE table_name = 'amfs_outcomes'
|
|
1807
1857
|
AND column_name IN (
|
|
1808
1858
|
'actions_taken', 'task_embedding', 'environment', 'task_text',
|
|
1809
|
-
'verified_by'
|
|
1859
|
+
'verified_by', 'covariates'
|
|
1810
1860
|
)
|
|
1811
1861
|
""",
|
|
1812
1862
|
)
|
|
@@ -1816,6 +1866,7 @@ class PostgresAdapter(AdapterABC):
|
|
|
1816
1866
|
self._has_outcome_env_col = "environment" in found
|
|
1817
1867
|
self._has_task_text_col = "task_text" in found
|
|
1818
1868
|
self._has_verified_by_col = "verified_by" in found
|
|
1869
|
+
self._has_covariates_col = "covariates" in found
|
|
1819
1870
|
|
|
1820
1871
|
# ------------------------------------------------------------------
|
|
1821
1872
|
# read
|
|
@@ -2500,6 +2551,90 @@ class PostgresAdapter(AdapterABC):
|
|
|
2500
2551
|
row = cur.fetchone()
|
|
2501
2552
|
return int(row["n"]) if row else 0
|
|
2502
2553
|
|
|
2554
|
+
def priority_stats(
|
|
2555
|
+
self,
|
|
2556
|
+
*,
|
|
2557
|
+
scope: SqlScope | None = None,
|
|
2558
|
+
agent_id: str | None = None,
|
|
2559
|
+
now: datetime | None = None,
|
|
2560
|
+
branch: str = "main",
|
|
2561
|
+
) -> tuple[int, float | None]:
|
|
2562
|
+
"""``(count, mean priority score)`` over the rows :meth:`list` returns.
|
|
2563
|
+
|
|
2564
|
+
What the tiers distribution needs and nothing more: the count fixes
|
|
2565
|
+
the Hot/Warm/Archive split (the tiers are rank bands) and the mean is
|
|
2566
|
+
the page's "average score". Computed by the database with
|
|
2567
|
+
:func:`priority_score_sql`; no entry row leaves it.
|
|
2568
|
+
"""
|
|
2569
|
+
now = now or datetime.now(timezone.utc)
|
|
2570
|
+
score, score_params = priority_score_sql(now)
|
|
2571
|
+
with self._pool.connection() as conn:
|
|
2572
|
+
with conn.cursor() as cur:
|
|
2573
|
+
conditions, params = list_conditions(
|
|
2574
|
+
self._namespace,
|
|
2575
|
+
None,
|
|
2576
|
+
include_superseded=False,
|
|
2577
|
+
branch=branch,
|
|
2578
|
+
scope=scope,
|
|
2579
|
+
agent_id=agent_id,
|
|
2580
|
+
branch_scope=self._branch_scope(cur, branch),
|
|
2581
|
+
)
|
|
2582
|
+
where = " AND ".join(conditions)
|
|
2583
|
+
cur.execute(
|
|
2584
|
+
f"SELECT COUNT(*) AS n, AVG({score}) AS mean "
|
|
2585
|
+
f"FROM amfs_memory_entries WHERE {where}",
|
|
2586
|
+
[*score_params, *params],
|
|
2587
|
+
)
|
|
2588
|
+
row = cur.fetchone()
|
|
2589
|
+
if not row or not row["n"]:
|
|
2590
|
+
return 0, None
|
|
2591
|
+
mean = row["mean"]
|
|
2592
|
+
return int(row["n"]), (float(mean) if mean is not None else None)
|
|
2593
|
+
|
|
2594
|
+
def list_by_priority(
|
|
2595
|
+
self,
|
|
2596
|
+
*,
|
|
2597
|
+
scope: SqlScope | None = None,
|
|
2598
|
+
agent_id: str | None = None,
|
|
2599
|
+
limit: int,
|
|
2600
|
+
offset: int = 0,
|
|
2601
|
+
now: datetime | None = None,
|
|
2602
|
+
branch: str = "main",
|
|
2603
|
+
) -> list[MemoryEntry]:
|
|
2604
|
+
"""One page of the rows :meth:`list` returns, highest priority first.
|
|
2605
|
+
|
|
2606
|
+
The order is :func:`priority_score_sql` descending with the stable
|
|
2607
|
+
``written_at DESC, entity_path, key`` tiebreak, so a page boundary is
|
|
2608
|
+
deterministic. A tier is a band of this ranking: rows 0–49 are Hot,
|
|
2609
|
+
50–249 Warm, the rest Archive — the caller picks *offset* and *limit*
|
|
2610
|
+
from the band and the database returns only that page.
|
|
2611
|
+
"""
|
|
2612
|
+
now = now or datetime.now(timezone.utc)
|
|
2613
|
+
score, score_params = priority_score_sql(now)
|
|
2614
|
+
with self._pool.connection() as conn:
|
|
2615
|
+
with conn.cursor() as cur:
|
|
2616
|
+
conditions, params = list_conditions(
|
|
2617
|
+
self._namespace,
|
|
2618
|
+
None,
|
|
2619
|
+
include_superseded=False,
|
|
2620
|
+
branch=branch,
|
|
2621
|
+
scope=scope,
|
|
2622
|
+
agent_id=agent_id,
|
|
2623
|
+
branch_scope=self._branch_scope(cur, branch),
|
|
2624
|
+
)
|
|
2625
|
+
where = " AND ".join(conditions)
|
|
2626
|
+
query = (
|
|
2627
|
+
f"SELECT {entry_select(self._has_is_artifact_col, self._has_validators_col)} "
|
|
2628
|
+
f"FROM amfs_memory_entries WHERE {where} "
|
|
2629
|
+
f"ORDER BY {score} DESC, written_at DESC, entity_path, key"
|
|
2630
|
+
)
|
|
2631
|
+
query, all_params = _paginate_sql(
|
|
2632
|
+
query, [*params, *score_params], limit=limit, offset=offset
|
|
2633
|
+
)
|
|
2634
|
+
cur.execute(query, all_params)
|
|
2635
|
+
rows = cur.fetchall()
|
|
2636
|
+
return [self._row_to_entry(r) for r in rows]
|
|
2637
|
+
|
|
2503
2638
|
def entry_authors(self, refs: list[tuple[str, str]]) -> dict[tuple[str, str], str]:
|
|
2504
2639
|
"""Who wrote each ``(entity_path, key)``, for the current version.
|
|
2505
2640
|
|
|
@@ -4125,6 +4260,15 @@ class PostgresAdapter(AdapterABC):
|
|
|
4125
4260
|
columns.append("environment")
|
|
4126
4261
|
placeholders.append("%s::jsonb")
|
|
4127
4262
|
params.append(json.dumps(env))
|
|
4263
|
+
if getattr(self, "_has_covariates_col", False):
|
|
4264
|
+
covariates = recorded_covariates({
|
|
4265
|
+
"covariates": record.covariates or None,
|
|
4266
|
+
"session_metadata": record.session_metadata or {},
|
|
4267
|
+
})
|
|
4268
|
+
if covariates:
|
|
4269
|
+
columns.append("covariates")
|
|
4270
|
+
placeholders.append("%s::jsonb")
|
|
4271
|
+
params.append(json.dumps(covariates, default=str))
|
|
4128
4272
|
task_embedding = self._outcome_embedding(record)
|
|
4129
4273
|
if task_embedding is not None:
|
|
4130
4274
|
columns.append("task_embedding")
|
|
@@ -4433,9 +4577,10 @@ class PostgresAdapter(AdapterABC):
|
|
|
4433
4577
|
conditions.append("committed_at >= %s")
|
|
4434
4578
|
params.append(since)
|
|
4435
4579
|
env_col = ", environment" if getattr(self, "_has_outcome_env_col", False) else ""
|
|
4580
|
+
cov_col = ", covariates" if getattr(self, "_has_covariates_col", False) else ""
|
|
4436
4581
|
sql = f"""
|
|
4437
4582
|
SELECT outcome_ref, outcome_type, committed_at, agent_id, actions_taken, situation,
|
|
4438
|
-
1 - (task_embedding <=> %s::vector) AS similarity{env_col}
|
|
4583
|
+
1 - (task_embedding <=> %s::vector) AS similarity{env_col}{cov_col}
|
|
4439
4584
|
FROM amfs_outcomes
|
|
4440
4585
|
WHERE {" AND ".join(conditions)}
|
|
4441
4586
|
ORDER BY task_embedding <=> %s::vector
|
|
@@ -4458,6 +4603,7 @@ class PostgresAdapter(AdapterABC):
|
|
|
4458
4603
|
"situation": row.get("situation"),
|
|
4459
4604
|
"actions_taken": _jsonb(row.get("actions_taken"), []),
|
|
4460
4605
|
"environment": _jsonb(row.get("environment"), {}) or {},
|
|
4606
|
+
"covariates": _jsonb(row.get("covariates"), {}) or {},
|
|
4461
4607
|
"similarity": sim,
|
|
4462
4608
|
})
|
|
4463
4609
|
return out
|
|
@@ -4665,8 +4811,9 @@ class PostgresAdapter(AdapterABC):
|
|
|
4665
4811
|
conditions.append("committed_at >= %s")
|
|
4666
4812
|
params.append(since)
|
|
4667
4813
|
env_col = ", environment" if getattr(self, "_has_outcome_env_col", False) else ""
|
|
4814
|
+
cov_col = ", covariates" if getattr(self, "_has_covariates_col", False) else ""
|
|
4668
4815
|
sql = f"""
|
|
4669
|
-
SELECT outcome_ref, outcome_type, committed_at, agent_id, actions_taken, situation{env_col}
|
|
4816
|
+
SELECT outcome_ref, outcome_type, committed_at, agent_id, actions_taken, situation{env_col}{cov_col}
|
|
4670
4817
|
FROM amfs_outcomes
|
|
4671
4818
|
WHERE {" AND ".join(conditions)}
|
|
4672
4819
|
ORDER BY committed_at DESC
|
|
@@ -4684,6 +4831,7 @@ class PostgresAdapter(AdapterABC):
|
|
|
4684
4831
|
"situation": row.get("situation"),
|
|
4685
4832
|
"actions_taken": _jsonb(row.get("actions_taken"), []),
|
|
4686
4833
|
"environment": _jsonb(row.get("environment"), {}) or {},
|
|
4834
|
+
"covariates": _jsonb(row.get("covariates"), {}) or {},
|
|
4687
4835
|
"similarity": 1.0,
|
|
4688
4836
|
} for row in rows]
|
|
4689
4837
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- Migration 014: the covariates of the task on the outcome row
|
|
2
|
+
--
|
|
3
|
+
-- An outcome records what was done (`actions_taken`) in what kind of task
|
|
4
|
+
-- (`situation`) under what runtime (`environment`). It did not record what
|
|
5
|
+
-- the task *was like*: the customer's plan, the app version the lookup
|
|
6
|
+
-- showed, the card's issuer country. When a rule changes for part of a
|
|
7
|
+
-- situation — the export fix stops working on paid plans and keeps working
|
|
8
|
+
-- on the free one — the situation's record turns contested (wins and losses
|
|
9
|
+
-- interleaved, no streak) and nothing in it says which runs the old action
|
|
10
|
+
-- still wins. On the 2026-10-21 regime study the recommendation kept the
|
|
11
|
+
-- stale action as `act` on 59 % of the first searches after such a change.
|
|
12
|
+
--
|
|
13
|
+
-- The covariates are the scalar attributes a run declared about the task
|
|
14
|
+
-- (`set_session_attributes`, `Run.begin(covariates=...)`) less its
|
|
15
|
+
-- environment keys and the situation label, copied here at commit from the
|
|
16
|
+
-- record so `amfs_core.actions.split_contested` can read them off the same
|
|
17
|
+
-- rows the priors are aggregated from. Scalars only; at most the attribute
|
|
18
|
+
-- bag's 20 keys. Written only when the record has any.
|
|
19
|
+
|
|
20
|
+
ALTER TABLE amfs_outcomes ADD COLUMN IF NOT EXISTS covariates JSONB;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/async_adapter.py
RENAMED
|
File without changes
|
{amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/evidence_sql.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/retention.py
RENAMED
|
File without changes
|
|
File without changes
|
{amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/tenant_context.py
RENAMED
|
File without changes
|
{amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/tenant_gucs.py
RENAMED
|
File without changes
|
{amfs_adapter_postgres-0.2.41 → amfs_adapter_postgres-0.2.43}/src/amfs_postgres/trace_partitions.py
RENAMED
|
File without changes
|