Adds SqlWriter: a pyodbc-backed writer that dedup-inserts into dbo.SyncQueue (IF NOT EXISTS guarded by UX_SyncQueue_Dedup), invokes dbo.usp_SyncApply, and reports applied SourceLogIDs. Connection is opened with autocommit=True per the controller revision: usp_SyncApply manages its own transaction internally (BEGIN/ROLLBACK), and an outer pyodbc transaction would conflict on ROLLBACK (SQL error 266). The dedup IF NOT EXISTS...INSERT is a single atomic statement. Integration test self-cleans via SourceFile='sqlw_test.accdb' marker; conn_str comes from the gitignored config.yaml (no hardcoded creds). Co-Authored-By: Claude <noreply@anthropic.com>
56 lines
1.9 KiB
Python
56 lines
1.9 KiB
Python
"""Integration test for sync.sql_writer.SqlWriter.
|
|
|
|
Validates the dedup INSERT (same SourceLogID is only ever enqueued once), the
|
|
``applied_log_ids`` query (rows flipped to ``applied`` come back in order), and
|
|
that ``call_apply`` invokes the proc without raising.
|
|
|
|
conn_str is read from the gitignored ``config.yaml`` via ``load_config``; no
|
|
credentials are hardcoded here. The test self-cleans using a throwaway
|
|
``SourceFile='sqlw_test.accdb'`` marker so no residue is left on SyncQueue.
|
|
"""
|
|
import os
|
|
import pytest
|
|
|
|
from sync.sql_writer import SqlWriter, QueueRow
|
|
from sync.config import load_config
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_insert_dedup_and_applied_ids():
|
|
if not os.environ.get("RUN_INTEGRATION"):
|
|
pytest.skip("integration")
|
|
cfg = load_config("config.yaml")
|
|
w = SqlWriter(cfg.sql_server.conn_str, "dbo.SyncQueue")
|
|
try:
|
|
cur = w._conn.cursor()
|
|
cur.execute("DELETE dbo.SyncQueue WHERE SourceFile='sqlw_test.accdb'")
|
|
qr = QueueRow(
|
|
source_file="sqlw_test.accdb",
|
|
source_table="T",
|
|
record_id="7",
|
|
target_schema="sync_test",
|
|
target_table="T_YEAR2026",
|
|
source_log_id=100,
|
|
operate_type="Insert",
|
|
row_data='{"ID":7}',
|
|
)
|
|
w.insert_queue_row(qr)
|
|
w.insert_queue_row(qr) # duplicate must be deduped (ignored)
|
|
cur.execute(
|
|
"SELECT COUNT(*) FROM dbo.SyncQueue "
|
|
"WHERE SourceFile='sqlw_test.accdb' AND SourceLogID=100"
|
|
)
|
|
assert cur.fetchone()[0] == 1
|
|
|
|
# call_apply must run without error (proc logic validated elsewhere).
|
|
w.call_apply(max_retries=5)
|
|
|
|
cur.execute(
|
|
"UPDATE dbo.SyncQueue SET Status='applied' "
|
|
"WHERE SourceFile='sqlw_test.accdb'"
|
|
)
|
|
assert w.applied_log_ids("sqlw_test.accdb") == [100]
|
|
finally:
|
|
cur.execute("DELETE dbo.SyncQueue WHERE SourceFile='sqlw_test.accdb'")
|
|
w.close()
|