distill: best practices from 2026-04-19 cross-project run
Adds 3 new topic files (ai-parallel-agents, api-integration, python-patterns) and extends 21 existing topic files with new gotchas and patterns surfaced from memory across tracked projects. Index updated accordingly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -98,3 +98,46 @@ Before deploying any new service, check:
|
||||
3. Switch to PostgreSQL **before the first deployment**, not after problems appear
|
||||
4. Add the database password to SOPS-encrypted secrets
|
||||
5. Verify the database connection works before adding consumers
|
||||
|
||||
## `ON CONFLICT DO NOTHING` Requires a Real Unique Constraint
|
||||
|
||||
SQLAlchemy `on_conflict_do_nothing()` and raw `ON CONFLICT DO NOTHING` only work when there is a matching unique constraint or unique index. Without one, the statement either silently does nothing or inserts a duplicate, depending on the exact phrasing.
|
||||
|
||||
**Trap:** "URL" looks like a natural unique key for a crawl/ingest table, so the LLM or developer adds `UNIQUE(url)` to make the upsert work. But URL content changes over time — two rows for the same URL at different timestamps are semantically distinct. The fake unique constraint then corrupts the model (or blocks legitimate re-ingestion).
|
||||
|
||||
**Rule:**
|
||||
|
||||
- If the natural key is truly unique (user ID, slug, message hash), add the unique constraint and use `on_conflict_do_nothing()`
|
||||
- If the natural key is *not* unique over time (URL, title, filename), use **query-before-insert** in a transaction, not a fake unique constraint
|
||||
- Don't invent unique constraints to make `ON CONFLICT` work — you're encoding a false invariant into the schema
|
||||
|
||||
## Alembic Multi-Schema Migrations
|
||||
|
||||
To run Alembic against multiple Postgres schemas in one database:
|
||||
|
||||
1. Set `include_schemas=True` in `env.py` so autogenerate sees non-default schemas
|
||||
2. Add an `include_name` filter so autogenerate only tracks the schemas you manage (otherwise it tries to "fix" `information_schema`, `pg_catalog`, etc.)
|
||||
3. **Issue `CREATE SCHEMA IF NOT EXISTS <name>`** before `run_migrations()` — otherwise the first migration fails on a missing schema
|
||||
|
||||
```python
|
||||
def include_name(name, type_, parent_names):
|
||||
if type_ == "schema":
|
||||
return name in {"app", "audit", "reporting"}
|
||||
return True
|
||||
|
||||
def run_migrations_online():
|
||||
connectable = engine_from_config(...)
|
||||
with connectable.connect() as connection:
|
||||
for schema in ("app", "audit", "reporting"):
|
||||
connection.execute(text(f'CREATE SCHEMA IF NOT EXISTS "{schema}"'))
|
||||
context.configure(
|
||||
connection=connection,
|
||||
include_schemas=True,
|
||||
include_name=include_name,
|
||||
...
|
||||
)
|
||||
with context.begin_transaction():
|
||||
context.run_migrations()
|
||||
```
|
||||
|
||||
Also set `version_table_schema` on `context.configure` if the Alembic version table should live in a specific schema rather than `public`.
|
||||
|
||||
Reference in New Issue
Block a user