Praca z bazą danych w Codex: schematy, migracje i zapytania, których działanie udowodnisz
Codex prowadzi pracę z bazą danych na stosie Drizzle i PostgreSQL jako potok: projektuje schemat, generuje migracje tylko „w przód” poleceniem drizzle-kit, pisze zapytania pod istniejące indeksy i udowadnia każdą zmianę na bazie wypełnionej danymi testowymi w worktree albo w środowisku chmurowym Codex. Ludzie przeglądają SQL migracji i dowody, a nie każdą wygenerowaną linię.
Product manager chce dashboardu raportowego, który agreguje zamówienia, przychód i zwroty dla każdego użytkownika w ujęciu dziennym, tygodniowym i miesięcznym. Tabela orders ma już dziesiątki milionów wierszy, obecne zapytania są wolne, a jeden blokujący CREATE INDEX w godzinach pracy położy checkout. Ta strona jest dla programisty, który prowadzi tę zmianę w Codex, i dla tech leada, który musi zdecydować, co znaczy „udowodnione jako bezpieczne”, zanim zmiana trafi na produkcję.
Co zyskasz, pracując z bazą danych w Codex
Dział zatytułowany „Co zyskasz, pracując z bazą danych w Codex”- Blok
AGENTS.md, który nie pozwala Codexowi edytować zastosowanych migracji ani dotykać niczego poza lokalną lub testową bazą. - Pięć promptów do skopiowania: projekt schematu, migracja, zapytania z testami, przebieg dowodowy w chmurze i cotygodniowy audyt zapytań.
- Skrypt konfiguracyjny środowiska chmurowego Codex, który daje każdemu zadaniu własny PostgreSQL.
- Konfigurację serwera MCP dla PostgreSQL w trybie tylko do odczytu, dzięki której Codex czyta prawdziwe plany zapytań.
- Zestaw weryfikacji (lint migracji, migracja od zera, różnicowe testy zapytań, asercje na planach) i jasną granicę tego, co nadal czyta człowiek.
Która powierzchnia Codex pasuje do którego zadania bazodanowego?
Dział zatytułowany „Która powierzchnia Codex pasuje do którego zadania bazodanowego?”Praca z bazą wyraźnie rozkłada się na powierzchnie Codex. Wybieraj według tego, do czego zadanie musi mieć dostęp.
| Zadanie | Powierzchnia | Dlaczego |
|---|---|---|
| Projekt schematu, iteracje | CLI albo rozszerzenie IDE, interaktywnie | Odpowiadasz na pytania projektowe na bieżąco |
| Kod migracji i zapytań | CLI z codex --worktree | Gałąź i wygenerowany SQL nie mieszają się z głównym checkoutem; lokalna baza jest wspólna, więc każdemu worktree daj własną bazę (createdb app_<branch> i ustaw na nią DATABASE_URL) |
| Dowód na danych w skali produkcyjnej | Zadanie w chmurze Codex (codex cloud exec) | Baza wypełniona danymi testowymi działa w kontenerze, a przebieg best-of-N (--attempts N) nie zajmuje twojej maszyny |
| Prawdziwe plany zapytań | CLI plus serwer MCP dla PostgreSQL tylko do odczytu | Codex czyta wynik EXPLAIN ze stagingu, zamiast zgadywać |
| Cotygodniowy audyt regresji | Automatyzacja w aplikacji desktopowej albo codex exec z harmonogramu | Działa bez ciebie i raportuje tylko to, co się zmieniło |
Flagi CLI na tej stronie sprawdzono na codex 0.157.1 i drizzle-kit 0.31.11. Mechanikę worktree opisuje przewodnik po worktree w Codex, a przewodnik po bazach danych dla wszystkich narzędzi zestawia Codexa z Claude Code i Cursorem.
Przekaż Codexowi reguły bazodanowe w AGENTS.md
Dział zatytułowany „Przekaż Codexowi reguły bazodanowe w AGENTS.md”Codex czyta AGENTS.md, zanim zacznie jakąkolwiek pracę, więc reguły bazodanowe należą tam, a nie do każdego promptu. Dodaj ten blok w katalogu głównym repozytorium:
## Database rules- Stack: PostgreSQL 16, Drizzle ORM. Schema in src/lib/db/schema.ts, migrations in drizzle/.- Generate migrations with `npx drizzle-kit generate --name <what_changed>`. Never hand-edit a migration that exists on main, and never edit drizzle/meta/ by hand.- Only connect to DATABASE_URL from the environment. Never connect to a host containing "prod" and never run a migration against anything but a local or test database.- Indexes on existing tables use CREATE INDEX CONCURRENTLY IF NOT EXISTS in scripts/concurrent/<index_name>.sql, never in drizzle/: drizzle-kit migrate runs every pending migration in one transaction, so CONCURRENTLY cannot go through it. Apply the file with `psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f <file>` after `npm run db:migrate`, then check pg_index.indisvalid for the new index.- Schema changes on existing tables follow expand/contract: add, backfill, switch reads, then drop in a later release. Never rename or drop a column in the same release that stops using it.- If `pg_isready` fails, start PostgreSQL with `service postgresql start`.- Before you finish: `npm run db:migrate`, then any new scripts/concurrent/ file with psql, `npm run db:lint`, `npm test -- tests/db`.npm run db:lint uruchamia linter migracji opisany w części o weryfikacji. Przewodnik po optymalizacji AGENTS.md pokazuje, jak utrzymać plik na tyle krótki, żeby takie reguły były przestrzegane.
Zaprojektuj schemat, zanim powstanie jakakolwiek migracja
Dział zatytułowany „Zaprojektuj schemat, zanim powstanie jakakolwiek migracja”Zacznij w CLI albo w rozszerzeniu IDE. Błędy w schemacie najdrożej się odkręca, więc pierwszy prompt zabrania generowania czegokolwiek, co dałoby się zastosować na bazie.
Zakwestionuj propozycję w tym samym wątku: co się dzieje z wierszem podsumowania, gdy zamówienie zostanie zwrócone miesiąc później, i czy (user_id, day) musi być unikalne. Odpowiedzi na takie pytania stają się później kryteriami akceptacji testów zapytań.
Wygeneruj migrację bezpieczną dla dużej tabeli
Dział zatytułowany „Wygeneruj migrację bezpieczną dla dużej tabeli”Uruchom sesję w worktree, żeby migracja trafiła na własną gałąź:
# Terminal, katalog główny repozytoriumcodex --worktreeTrzy fakty o drizzle-kit kształtują ten prompt. Generuje on migracje tylko „w przód”: lista poleceń w 0.31.11 (generate, migrate, push, check, up, drop i inne) nie zawiera polecenia down ani rollback, a drop usuwa plik migracji, zamiast cofać zmiany w bazie. Wygenerowany CREATE INDEX jest zwykłym, blokującym poleceniem. A drizzle-kit migrate uruchamia wszystkie oczekujące migracje w jednej transakcji. Plan wycofania i indeksy tworzone współbieżnie musisz więc zamówić sam, a indeksy współbieżne nie mogą trafić do drizzle/.
Indeks współbieżny leży poza drizzle/, bo spotykają się tu dwie reguły. PostgreSQL nie pozwala uruchomić CREATE INDEX CONCURRENTLY wewnątrz bloku transakcji, a drizzle-kit migrate przekazuje wszystkie oczekujące migracje do migratora PostgreSQL z drizzle-orm, który stosuje je w jednej transakcji (sprawdzone w drizzle-orm 0.45.3, 2026-09-26). Własna migracja Drizzle (drizzle-kit generate --custom) działa w tej samej transakcji, więc indeks potrzebuje osobnego, nietransakcyjnego kroku psql we wdrożeniu, po db:migrate. Nieudane budowanie współbieżne zostawia indeks INVALID, a IF NOT EXISTS po cichu go wtedy pomija; dlatego krok 4 sprawdza indisvalid, zamiast ufać czystemu kodowi wyjścia. Wzorce migracji baz danych opisują dokładnie expand/contract i backfille.
Pisz zapytania z testami, które naprawdę mogą wykryć błąd
Dział zatytułowany „Pisz zapytania z testami, które naprawdę mogą wykryć błąd”Zapytanie, które przechodzi kontrolę typów i zwraca wiersze, niewiele dowodzi. Prompt poniżej żąda dwóch rodzajów dowodu: wyników porównanych z niezależną wyrocznią w SQL i planów sprawdzonych pod kątem indeksu, którego każde zapytanie powinno użyć.
To test różnicowy wyłapuje błędne odpowiedzi: wyrocznia czyta surowe zamówienia i nic nie wie o tabelach podsumowań, więc podwójnie policzony zwrot albo przesunięcie strefy czasowej wychodzi jako niezgodność. Testy planów na małym zestawie danych testowych bywają mylące, bo planer na małych tabelach woli skan sekwencyjny; dlatego prompt umieszcza je w osobnym pliku, który działa tylko z PLAN_TESTS=1. Lokalna bramka npm test -- tests/db je pomija, a opisany niżej przebieg dowodowy w chmurze włącza je na zbiorze danych w skali produkcyjnej.
Udowodnij zmianę na danych w skali produkcyjnej w zadaniu chmurowym Codex
Dział zatytułowany „Udowodnij zmianę na danych w skali produkcyjnej w zadaniu chmurowym Codex”Baza na laptopie ma kilka tysięcy wierszy. Pytania, które się liczą (ile trwa budowa indeksu współbieżnego, czy planer wybierze go przy 50 milionach wierszy), wymagają większego zbioru danych. Środowisko chmurowe Codex daje każdemu zadaniu własny kontener, więc każde zadanie może mieć własny, jednorazowy PostgreSQL.
Wpisz skrypt konfiguracyjny środowiska w ustawieniach webowych Codex, w sekcji Environments, i nazwij środowisko db-proof: codex cloud exec --env przyjmuje nazwę środowiska albo jego ID (sprawdzone w codex 0.157.1), a polecenie dowodowe poniżej używa nazwy.
#!/usr/bin/env bash# Skrypt konfiguracyjny środowiska chmurowego Codexset -euo pipefail
apt-get update && apt-get install -y --no-install-recommends postgresql postgresql-contribnpm ci
service postgresql startsu postgres -c "createuser --superuser root" # uwierzytelnianie peer dla użytkownika root kontenera, bez hasłacreatedb app_test
# Sprawdź, że baza odpowiada. Migracje uruchamia zadanie, żeby mogło zmierzyć ich czaspg_isreadyUstaw DATABASE_URL na postgresql:///app_test?host=/var/run/postgresql jako zmienną środowiskową na tej samej stronie ustawień, a nie jako sekret, żeby faza agenta mogła ją odczytać niezależnie od tego, jak ograniczone są sekrety (i tak nie zawiera hasła). Nie zakładaj, że serwer uruchomiony przez skrypt konfiguracyjny nadal działa, gdy startuje agent; reguła w AGENTS.md mówi agentowi, jak go uruchomić.
Wypchnij gałąź, a potem zleć zadanie dowodowe:
ID zadania znajdziesz poleceniem codex cloud list --env db-proof. Wynik sprawdzisz poleceniem codex cloud status TASK_ID, a jeśli zadanie coś zmieniło, także codex cloud diff TASK_ID. Raport to artefakt, który dołączasz do pull requesta. Wypełnienie bazy 50 milionami wierszy wydłuża każdy przebieg, więc trzymaj liczbę wierszy na poziomie, który ujawnia interesujący cię plan; przewodnik po środowiskach chmurowych opisuje cache i skrypty utrzymaniowe, które przyspieszają kolejne przebiegi.
Pozwól Codexowi czytać prawdziwe plany zapytań przez MCP
Dział zatytułowany „Pozwól Codexowi czytać prawdziwe plany zapytań przez MCP”Dane testowe odpowiadają na pytanie „czy to bezpieczne”. Baza stagingowa z prawdziwym ruchem odpowiada na pytanie „które zapytania są dziś wolne”. Postgres MCP Pro (PyPI postgres-mcp; ostatnie wydanie na PyPI to 0.3.0 z 2025-05-16, sprawdzone 2026-09-26) udostępnia m.in. narzędzia explain_query, get_top_queries i analyze_query_indexes. Uruchamiaj go w trybie restricted, który ogranicza go do transakcji tylko do odczytu z limitem czasu wykonania, i łącz się rolą tylko do odczytu:
# ~/.codex/config.toml. env_vars przekazuje DATABASE_URI z twojej powłoki; nic tajnego tu nie trafia[mcp_servers.postgres]command = "uvx"args = ["postgres-mcp", "--access-mode=restricted"]env_vars = ["DATABASE_URI"]enabled_tools = ["list_schemas", "get_object_details", "explain_query", "get_top_queries", "analyze_query_indexes"]Wyeksportuj DATABASE_URI z connection stringiem roli tylko do odczytu na stagingu, zanim uruchomisz codex, i sprawdź wpis poleceniem codex mcp get postgres. Starszy pakiet @modelcontextprotocol/server-postgres jest na npm oznaczony jako wycofany; nie kopiuj fragmentów, które go używają. Przewodnik po serwerach MCP dla baz danych zawiera SQL roli tylko do odczytu i rozszerzenia potrzebne narzędziom do indeksów (pg_stat_statements, hypopg). Przewodnik omawia też alternatywy, takie jak Supabase i DBHub. Jeśli pakiet bez nowego wydania od maja 2025 roku jest dla twojego zespołu problemem, DBHub nadal dostaje nowe wydania. Konfiguracja MCP w Codex opisuje tryby zatwierdzania i trzymanie sekretów poza config.toml.
Audytuj wydajność zapytań co tydzień
Dział zatytułowany „Audytuj wydajność zapytań co tydzień”Gdy dashboard trafi na produkcję, regresje przychodzą razem ze zwykłą pracą nad funkcjami. Zaplanuj audyt jako automatyzację wątku w aplikacji desktopowej Codex, żeby każdy przebieg pamiętał poprzedni, z sandboxem tylko do odczytu i opisanym wyżej serwerem MCP. Przewodnik po automatyzacjach Codex opisuje konfigurację, sandbox i uruchamianie tego samego promptu przez codex exec na stale włączonym hoście.
Jak zweryfikować pracę Codexa na bazie danych bez czytania każdej linii?
Dział zatytułowany „Jak zweryfikować pracę Codexa na bazie danych bez czytania każdej linii?”Zmiany w bazie to jedna z niewielu klas zmian, w których człowiek nadal czyta sam kod, więc celem jest zawężenie tej lektury do SQL migracji i jednej strony dowodów. Podejście „dowody zamiast diffów” wyjaśnia ten podział.
-
Zlintuj migrację. Squawk (
squawk-clina npm) wyłapuje blokujące budowanie indeksów, niebezpieczne zmiany kolumn i inne zagrożenia związane z blokadami w migracjach PostgreSQL. Podepnij go jakodb:lint, na przykładnpx --package squawk-cli squawk drizzle/*.sql scripts/concurrent/*.sql, i uruchamiaj w CI przy każdym pull requeście, który dotykadrizzle/alboscripts/concurrent/. -
Zastosuj migracje od zera, dwa razy. CI tworzy pustą bazę, uruchamia wszystkie migracje, uruchamia je ponownie (nic nie może się zastosować drugi raz), stosuje pliki z
scripts/concurrent/przezpsqli wykonujenpx drizzle-kit check, żeby wyłapać niespójne metadane migracji. -
Uruchom testy różnicowe i testy planów. Testy zapytań porównują każdy wynik z Drizzle z niezależnym agregatem w SQL i sprawdzają zamierzony indeks. Niepowodzenie oznacza błędną odpowiedź albo utracony indeks, a nie kwestię stylu.
-
Dołącz raport z przebiegu dowodowego w chmurze. Pull request zawiera czasy, sprawdzenie
indisvalidi plany z przebiegu na danych w skali produkcyjnej. Bez raportu nie ma merge’a. -
Wskazana osoba czyta SQL i zatwierdza zmianę. Programista, który zlecił zadanie, czyta każdy plik
.sqli notatkę o wycofaniu, które są krótkie w porównaniu z wygenerowanym kodem aplikacji. Przy zmianach w tabelach powyżej ustalonego w zespole progu wielkości analizę blokad zatwierdza druga osoba (tech lead albo DBA).@codex reviewna pull requeście to przydatne dodatkowe przejście, a nie zatwierdzenie.
Kod aplikacji wokół zapytań (typy, podpięcie w serwisach) przechodzi te same bramki co każda inna zmiana wprowadzona przez Codexa: kontrolę typów, lint, testy i review, opisane w przewodniku testowanie z Codex.
Co się psuje, gdy Codex pracuje z bazą danych?
Dział zatytułowany „Co się psuje, gdy Codex pracuje z bazą danych?”| Objaw | Prawdopodobna przyczyna | Jak z tego wyjść |
|---|---|---|
| Wdrożenie kończy się błędem „CREATE INDEX CONCURRENTLY cannot run inside a transaction block” | drizzle-kit migrate stosuje wszystkie oczekujące migracje w jednej transakcji | Usuń polecenie CONCURRENTLY z drizzle/, uruchom je przez psql poza migratorem jako osobny krok wdrożenia, usuń pozostawiony indeks INVALID poleceniem DROP INDEX CONCURRENTLY i spróbuj ponownie |
drizzle-kit check nie przechodzi albo migracja stosuje się drugi raz | Codex ręcznie edytował zastosowaną migrację albo drizzle/meta/ | Przywróć te pliki z main, zmień tylko schema.ts, wygeneruj ponownie; zachowaj regułę w AGENTS.md, która tego zabrania |
| Testy planów przechodzą lokalnie, a dashboard na produkcji jest wolny | Dane testowe są małe albo mają równomierny rozkład, więc planer wybrał inaczej | Wypełnij bazę danymi o rozkładzie zbliżonym do produkcji, uruchamiaj ANALYZE i trzymaj asercje na planach w przebiegu dowodowym w chmurze |
| Codex „naprawia” każde wolne zapytanie nowym indeksem | Prompt nagradzał wyłącznie szybkość | Wymagaj, żeby każdy indeks wskazywał zapytanie, któremu służy, i plan przed zmianą i po niej, oraz pytaj, który istniejący indeks staje się zbędny |
| Sumy na dashboardzie nie zgadzają się dla użytkowników spoza UTC | Granice dni liczone w UTC | Przekazuj strefę czasową użytkownika do każdego zapytania i trzymaj zamówienie z 23:30 UTC w danych testowych (fixture) testu różnicowego |
| Dwie sesje w worktree kończą się błędem „relation already exists” albo widzą nawzajem swoje wiersze testowe | Każde worktree wskazuje na ten sam lokalny DATABASE_URL, więc równoległe migracje i dane testowe kolidują | Utwórz osobną bazę dla każdego worktree (createdb app_<branch>) i ustaw DATABASE_URL w środowisku tego worktree |
| Zadanie w chmurze zgłasza „connection refused” | PostgreSQL uruchomiony podczas konfiguracji nie działa w fazie agenta | Zachowaj w AGENTS.md regułę z pg_isready i service postgresql start oraz sprawdź, czy zmienna środowiskowa zawiera URL do gniazda |
| Serwer MCP nie startuje albo nie pokazuje narzędzi | Brak uvx, niewyeksportowane DATABASE_URI albo literówka w enabled_tools | Uruchom bezpośrednio uvx postgres-mcp --help, wyeksportuj zmienną przed startem codex i odczytaj prawdziwe nazwy narzędzi przez /mcp verbose |
Dokąd dalej z pracą na bazie danych w Codex
Dział zatytułowany „Dokąd dalej z pracą na bazie danych w Codex”- Skonfiguruj serwer raz, a porządnie: serwery MCP dla baz danych i zabezpieczanie serwerów MCP.
- Planuj migracje rozciągnięte na kilka wydań: wzorce migracji baz danych i wzorce optymalizacji SQL.
- Wdrażaj zmianę razem z aplikacją: automatyzacja wdrożeń z Codex.
- Profiluj to, co znajdzie audyt: optymalizacja wydajności z Codex.
- Daj każdemu zadaniu agenta własną bazę: efemeryczne środowiska.
- Ten sam przepływ w innych narzędziach: praca z bazą danych w Claude Code i projektowanie schematu w Cursorze.