Overview
This task (milestone M2) adds SyncDatabase, a handle that names the database that sync code uses. It also adds a test guard that fails when code queries the default database by mistake.
Background & Motivation
Sync code reaches the database in two implicit ways. ORM calls go through the host DATABASE_ROUTERS. Raw SQL and transactions always use "default". The archive is a second database, so archive code must name its database in every call.
The SQL backend also depends on the database. Today one backend object is chosen from the default connection. If the host uses PostgreSQL, the archive still uses SQLite, so each database needs its own backend.
Design: spec. Plan: implementation plan, Task 4.
Description & Expected Outcomes
SyncDatabase has two forms:
- The routed default handle. It reproduces today's behavior exactly: ORM calls go through the routers, and raw SQL and transactions use
"default".
- A pinned handle for an explicit alias. All calls, ORM and raw SQL, go to that alias.
The handle gives a model manager, a connection, a SQL backend, transactions, a cursor, and the current instance with an incremented counter. The module-level begin_transaction keeps its behavior.
The test guard is a context manager. It fails with the SQL text when a query reaches the default database inside it.
Deliverables & Contracts
The task delivers:
SyncDatabase in morango/sync/db.py, with the members that spec §3.3 lists.
assert_no_default_db_queries() in tests/testapp/tests/helpers.py.
- The module-level
begin_transaction and DBBackend names, with today's behavior.
Acceptance Criteria
Technical Pointers & Architecture
- Target Components:
morango/sync/db.py:15-37 (begin_transaction), morango/sync/backends/utils.py (load_backend), morango/models/core.py:191 (get_current_instance_and_increment_counter).
- Related Patterns:
tests/testapp/testapp/db.py (TestingRouter) is a router that sends ORM calls to another database. The routed default handle must keep that behavior.
- Data Model & Schema Considerations: None.
- Resilience & Failure Modes: The handle adds no fallback. A wrong alias fails with the Django error.
Notes & Tradeoffs
Metadata
- Complexity: Medium
- Target Branch: release-v0.9.x
AI Usage
Drafted with Claude (Claude Code) from the approved design spec and implementation plan. The author reviewed the requirements, and the code references were checked against the release-v0.9.x codebase.
Overview
This task (milestone M2) adds
SyncDatabase, a handle that names the database that sync code uses. It also adds a test guard that fails when code queries the default database by mistake.Background & Motivation
Sync code reaches the database in two implicit ways. ORM calls go through the host
DATABASE_ROUTERS. Raw SQL and transactions always use"default". The archive is a second database, so archive code must name its database in every call.The SQL backend also depends on the database. Today one backend object is chosen from the default connection. If the host uses PostgreSQL, the archive still uses SQLite, so each database needs its own backend.
Design: spec. Plan: implementation plan, Task 4.
Description & Expected Outcomes
SyncDatabasehas two forms:"default".The handle gives a model manager, a connection, a SQL backend, transactions, a cursor, and the current instance with an incremented counter. The module-level
begin_transactionkeeps its behavior.The test guard is a context manager. It fails with the SQL text when a query reaches the default database inside it.
Deliverables & Contracts
The task delivers:
SyncDatabaseinmorango/sync/db.py, with the members that spec §3.3 lists.assert_no_default_db_queries()intests/testapp/tests/helpers.py.begin_transactionandDBBackendnames, with today's behavior.Acceptance Criteria
SyncDatabase.default().manager(Store)isStore._default_manager.default2returns a manager that usesdefault2.backendof a SQLite alias is the SQLite wrapper.current_instance_and_increment_counter()on the default handle increments the current instance counter by 1.defaultand passes on a query todefault2.Technical Pointers & Architecture
morango/sync/db.py:15-37(begin_transaction),morango/sync/backends/utils.py(load_backend),morango/models/core.py:191(get_current_instance_and_increment_counter).tests/testapp/testapp/db.py(TestingRouter) is a router that sends ORM calls to another database. The routed default handle must keep that behavior.Notes & Tradeoffs
Metadata
AI Usage
Drafted with Claude (Claude Code) from the approved design spec and implementation plan. The author reviewed the requirements, and the code references were checked against the
release-v0.9.xcodebase.