{% extends "admin/change_form.html" %} {% load i18n admin_modify %} {% block extrastyle %} {{ block.super }} {% endblock %} {% block object-tools %} {{ block.super }} {# Hidden sibling forms for the partitioning + sync POST actions. They live #} {# outside the main admin
so they don't nest (HTML5 disallows it — #} {# nesting silently submits the outer form). The visible inputs/buttons #} {# below target these via the HTML5 `form="..."` attribute. #} {% csrf_token %}
{% endblock %} {# Suppress the default bottom submit_row — we render it inside `after_field_sets` #} {# below, immediately above Partitioning & sync, so save/delete sit close to the #} {# field sets instead of below the operator panel. #} {% block submit_buttons_bottom %}{% endblock %} {% block after_field_sets %} {{ block.super }}
{% submit_row %}

Partitioning & sync

Current settings

{% if current_partition_count_override is not None %} {% endif %} {% if current_partition_size_override is not None %} {% endif %} {% if current_partition_mode_override is not None %} {% endif %} {% if current_partitioning_keys_override is not None %} {% endif %}
partitioning_enabled {{ partitioning_enabled|default:"None" }}
partition_mode {{ current_partition_mode|default:"None" }}
partition_format {{ current_partition_format|default:"None" }}
partition_size {{ current_partition_size|default:"None" }}
partition_count {{ current_partition_count|default:"None" }}
partition_count_override {{ current_partition_count_override }} (pinned, applies on next reset)
partition_size_override {{ current_partition_size_override }} (pinned, applies on next reset)
partition_mode_override {{ current_partition_mode_override }} (pinned, applies on next reset)
partitioning_keys_override {{ current_partitioning_keys_override }} (pinned, applies on next reset)
partitioning_keys {{ current_partition_keys|default:"None" }}

Repartition & resync

Pause the schedule first (buttons below) to avoid racing the scheduled sync. This stages the partition settings and kicks off a non-billable workflow with reset_pipeline=true — repartitioning without a reset would mix old and new layouts in the same Delta table and corrupt it. The schedule auto-pauses for the run and unpauses on success.

Pick the partition mode (defaults to the current one). Keep the mode and change only its knob to repartition in place; change the mode to switch strategy — most often md5datetime on a date column when the primary key has one (the pipeline only auto-selects datetime for columns literally named created_at/inserted_at).

{% if available_columns %} {% else %} {% endif %} md5 hashes one or more keys together; datetime/numerical use a single column. Leave blank for md5 to use the table's primary keys.

Schedule

The scheduled sync uses Temporal's OnlyOne overlap policy, but ad-hoc admin runs bypass the schedule and can race with it. Pause the schedule before doing repartition or trigger-sync work, then unpause when finished.

If the schedule is missing entirely (pause/unpause/sync fail with "workflow not found", typically after an interrupted source creation), recreate it below. This also works as a repair when the schedule exists: it is updated in place. No run is triggered; kick one off with "Trigger sync" below, which is non-billable by default.

Trigger ad-hoc sync

Use this for non-repartition cases (e.g. retrying a failed sync). Repartition already triggers its own non-billable reset resync — don't double up. Pause the schedule first if you have any chance of overlap with the regular run.

Temporal schedule

View schedule in Temporal
{% if cdc_extraction_schedule_id %}
View CDC extraction schedule in Temporal

For CDC schemas, the per-schema schedule above is paused once streaming starts. This source-level schedule is what drives the actual change capture.

{% endif %}

Jobs{% if page_obj %} ({{ page_obj.paginator.count }} total){% endif %}

{% if page_obj and page_obj.object_list %} {% for job in page_obj %} {% endfor %}
Job ID Status Created at Finished at Rows synced Temporal workflow Logs Error
{{ job.id }} {% if job.status == "Running" %} Running {% elif job.status == "Completed" %} Completed {% elif job.status == "Failed" %} Failed {% elif job.status == "BillingLimitReached" %} Billing limit reached {% elif job.status == "BillingLimitTooLow" %} Billing limit too low {% else %} {{ job.status }} {% endif %} {{ job.created_at|date:"Y-m-d H:i:s" }} {% if job.finished_at %}{{ job.finished_at|date:"Y-m-d H:i:s" }}{% else %}—{% endif %} {% if job.rows_synced is not None %}{{ job.rows_synced }}{% else %}—{% endif %} {% if job.workflow_id and job.workflow_run_id %} View workflow {% else %} — {% endif %} {% if job.workflow_id %} View logs {% else %} — {% endif %} {% if job.latest_error %} {{ job.latest_error|truncatechars:80 }}
View in error tracking {% else %} — {% endif %}
{% if page_obj.paginator.num_pages > 1 %}
{% if page_obj.has_previous %} « First ‹ Previous {% endif %} Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }} {% if page_obj.has_next %} Next › Last » {% endif %}
{% endif %} {% else %}
No jobs found for this schema.
{% endif %}
{% endblock %}