Skip to content

Commit 8421029

Browse files
fix executemany with returning=True instrumentation for psycopg
1 parent da7329d commit 8421029

3 files changed

Lines changed: 462 additions & 12 deletions

File tree

drift/instrumentation/psycopg/e2e-tests/src/app.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,75 @@ def test_cursor_iteration():
317317
except Exception as e:
318318
return jsonify({"error": str(e)}), 500
319319

320+
@app.route("/test/executemany-returning")
321+
def test_executemany_returning():
322+
"""Test executemany with returning=True.
323+
324+
Tests whether the instrumentation correctly handles executemany with returning=True.
325+
"""
326+
try:
327+
with psycopg.connect(get_conn_string()) as conn, conn.cursor() as cur:
328+
# Create temp table
329+
cur.execute("CREATE TEMP TABLE batch_test (id SERIAL, name TEXT)")
330+
331+
# Use executemany with returning
332+
params = [("Batch User 1",), ("Batch User 2",), ("Batch User 3",)]
333+
cur.executemany(
334+
"INSERT INTO batch_test (name) VALUES (%s) RETURNING id, name",
335+
params,
336+
returning=True
337+
)
338+
339+
# Fetch results from each batch
340+
results = []
341+
for result in cur.results():
342+
row = result.fetchone()
343+
if row:
344+
results.append({"id": row[0], "name": row[1]})
345+
346+
conn.commit()
347+
348+
return jsonify({
349+
"count": len(results),
350+
"data": results
351+
})
352+
except Exception as e:
353+
return jsonify({"error": str(e)}), 500
354+
355+
# ============================================================================
356+
# BUG HUNTING TEST ENDPOINTS
357+
# These endpoints expose confirmed bugs in the instrumentation
358+
# ============================================================================
359+
360+
@app.route("/test/cursor-scroll")
361+
def test_cursor_scroll():
362+
"""Test cursor.scroll() method.
363+
364+
BUG: The MockCursor and InstrumentedCursor classes don't implement
365+
the scroll() method. In replay mode, scroll() causes "no result available"
366+
error on subsequent fetchone() calls.
367+
"""
368+
try:
369+
with psycopg.connect(get_conn_string()) as conn, conn.cursor() as cur:
370+
cur.execute("SELECT id, name FROM users ORDER BY id")
371+
372+
# Fetch first row
373+
first = cur.fetchone()
374+
375+
# Scroll back to start
376+
cur.scroll(0, mode='absolute')
377+
378+
# Fetch first row again
379+
first_again = cur.fetchone()
380+
381+
return jsonify({
382+
"first": {"id": first[0], "name": first[1]} if first else None,
383+
"first_again": {"id": first_again[0], "name": first_again[1]} if first_again else None,
384+
"match": first == first_again
385+
})
386+
except Exception as e:
387+
return jsonify({"error": str(e)}), 500
388+
320389

321390
if __name__ == "__main__":
322391
sdk.mark_app_as_ready()

drift/instrumentation/psycopg/e2e-tests/src/test_requests.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,6 @@ def make_request(method, endpoint, **kwargs):
8080

8181
make_request("GET", "/test/cursor-iteration")
8282

83+
make_request("GET", "/test/executemany-returning")
84+
8385
print("\nAll requests completed successfully")

0 commit comments

Comments
 (0)