Skip to content

Commit 4316715

Browse files
fastapi-sqlalchemy-pg-catalog: clarify simple-Query semantics on parameterized SQL
Copilot review noted (correctly) that the README + main.py docstring described the pg_class probe as "parameter-less SQL", which conflicts with the recorded mock carrying 7 bind values. psycopg2 in fact uses the simple-Query protocol even when the source SQL is parameterized: it substitutes %(param)s placeholders client-side and emits the resulting inlined SQL as a single Q packet (no Bind/Execute frames). The bind values exist at the application layer; the wire shape is simple-Query. Both docs now say so explicitly so a reader doesn't see the recorded bind-value list and conclude the wire path must be extended-Query. Signed-off-by: Akash Kumar <meakash7902@gmail.com>
1 parent 3203a0a commit 4316715

2 files changed

Lines changed: 17 additions & 5 deletions

File tree

fastapi-sqlalchemy-pg-catalog/README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,14 @@ asymmetry (keploy/integrations#193).
88

99
At app boot, SQLAlchemy's `Base.metadata.create_all(engine)` issues a
1010
`pg_catalog.pg_class` probe per declared table to decide whether to
11-
skip `CREATE TABLE`. With psycopg2 + parameter-less SQL the probe
12-
goes through the **simple-query** protocol path.
11+
skip `CREATE TABLE`. psycopg2 sends the probe over the
12+
**simple-query** protocol (`Q` packet) even though the source SQL is
13+
parameterized — it substitutes the `%(param)s` placeholders
14+
client-side and emits the resulting inlined SQL as a single
15+
statement, with no `Bind`/`Execute` frames. So the wire shape is
16+
simple-Query carrying inlined bind values; the recorded mock keeps
17+
the parameter list for matching, but the dispatcher's classifier
18+
sees a simple-Query CATALOG request.
1319

1420
In `pkg/postgres/v3/replayer/dispatcher/dispatcher.go`:
1521

fastapi-sqlalchemy-pg-catalog/app/main.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,17 @@
44
``Base.metadata.create_all`` table-existence probe.
55
66
Boot sequence:
7-
1. SQLAlchemy creates an engine over psycopg2 (simple-query for
8-
parameter-less SQL).
7+
1. SQLAlchemy creates an engine over psycopg2. psycopg2 sends queries
8+
via the simple-Query protocol (``Q`` packet) even when the source
9+
SQL is parameterized: it does client-side ``%(param)s`` substitution
10+
and emits the resulting string as a single inlined statement
11+
(no ``Bind``/``Execute`` frames).
912
2. ``Base.metadata.create_all(engine)`` issues one
1013
``SELECT pg_catalog.pg_class.relname ...`` probe per declared table
11-
to decide whether each ``CREATE TABLE`` should be skipped.
14+
to decide whether each ``CREATE TABLE`` should be skipped. The
15+
probe SQL has 7 parameters (table name, relkind chars, namespace);
16+
psycopg2 inlines them before the wire write, so the dispatcher sees
17+
a simple-Query statement that classifies as ``ClassCatalog``.
1218
3. FastAPI starts serving requests.
1319
1420
The probe is what hits the dispatcher's ``case match.ClassCatalog``

0 commit comments

Comments
 (0)