Skip to content
Aabha AI Academy

Module 4 of 9 · Lesson 11 of 26

Backfill existing data in bounded batches

Work through backfill existing data in bounded batches using a runnable reference, a focused regression check and a local extension.

Read in any order. All lessons stay open, including after an unanswered or incorrect check.

In this lesson you will backfill existing data in bounded batches. Work with the Equipment Rental API in the downloadable lab. The reference is a complete solution with separate lesson checks, so you can inspect the answer, make a deliberate local change and verify its behavior.
A backfill evolves data that already exists. During an expand stage, old equipment rows may have condition=NULL while new writes already supply a valid value. backfill_condition selects a bounded batch of missing ids, updates only rows still missing the value, and commits that batch through engine.begin. Rerunning after interruption skips filled rows, so the job is idempotent.

Batching limits lock duration and transaction size. It does not make every large migration risk-free: indexing, application compatibility and concurrent writers still need review. First deploy code that tolerates the expanded shape, run and observe the backfill, verify no missing values remain, and then add the final constraint in a later migration. The bundled 0002 migration is a small-data example in one transaction. The separate helper demonstrates independent batch commits; using it inside an existing migration transaction would be a different behavior. Count processed batches or rows without logging learner records or credentials. Do not overwrite non-null values merely to make every row look identical.
Worked source: equipment/services.py, backfill_condition.

The lesson11 fixture temporarily makes condition nullable only in its disposable database. It creates three missing values, uses a batch size of two, expects two committed batches, reruns expecting zero, and restores NOT NULL. This intentionally simulates an intermediate schema rather than weakening the application's final schema.
pythonCopyable
def backfill_condition(engine, batch_size=100):
    if batch_size < 1:
        raise ValueError("Batch size must be positive")
    batches = 0
    while True:
        with engine.begin() as connection:
            identifiers = (
                connection.execute(
                    select(Equipment.id)
                    .where(Equipment.condition.is_(None))
                    .order_by(Equipment.id)
                    .limit(batch_size)
                )
                .scalars()
                .all()
            )
            if not identifiers:
                break
            connection.execute(
                update(Equipment)
                .where(Equipment.id.in_(identifiers), Equipment.condition.is_(None))
                .values(condition="ready")
            )
        batches += 1  # each batch commits; rerunning ignores already-filled rows
    return batches
TerminalPython 3.13 virtual environment; Docker running; extracted lab directory
python run_checks.py -k lesson11

Expected result The selected lesson test passes against a new temporary PostgreSQL database; the container is removed afterward.

Keep for reference

Equipment Rental lab and lesson checks

ZIP containing Python source, real Alembic migrations, 26 lesson checks, a dependency lock and text instructions. Extract it before following the local exercise.

Download Equipment Rental lab and lesson checks

Practise locally

Add a valid custom condition to one item and several missing values to your own expanded test schema. Stop after one batch, rerun the job, and verify the custom value survives while all missing values become ready. Record batch counts and the final null count. Write the verification query you would require before a later NOT NULL migration.

The lesson check verifies the reference behavior. Add your own assertions for your change. Local practice is not uploaded or scored by this learning release.

Pause and reflect

What failure does this lesson prevent, and which assertion in lesson11 would expose it?

Use a concrete input, expected result and limitation from your local work. Saving a reflection does not certify the project.

Optional knowledge check

What makes this backfill safe to resume?

It rewrites every row on every run, including user-supplied values.

Try another answer. That could destroy valid existing values and repeatedly expand the work.

Run every batch inside one surrounding transaction and call it independently committed.

Try another answer. A surrounding transaction changes the durability and lock-duration behavior.

It changes only rows still missing the value and commits bounded batches.

Correct. Completed rows are skipped after interruption, and each batch has a clear transaction boundary.

This practice does not assess your project or award a certificate.

Your reading progress

Progress is saved in this browser when storage is available.

Sign in to save across devices · Create an optional account