alexcinovoj.devby TechTide AI
Back to Airtable proof
Pattern · Airtable exit and rescue

Preserving linked records

Linked records are the part of an Airtable base with the most business meaning and the least schema rigour. They must be translated deliberately, not inferred by an importer.

Sanitized reference pattern

This is a generalised method, not a client case study. No client names, schemas, data, or outcomes are published here, and no results are claimed on a client's behalf.

Short answer

What is preserving Airtable linked records in a migration?

Linked records are the part of an Airtable base with the most business meaning and the least schema rigour. They must be translated deliberately, not inferred by an importer.

Method

  • Classify each link field as one-to-many or many-to-many by inspecting actual data, not the field label.
  • Give every table a stable surrogate key and keep the original Airtable record ID in an indexed column for the whole migration window.
  • Translate one-to-many links to a foreign key; translate many-to-many links to a join table with its own primary key.
  • Replace lookups with views or generated columns, and rollups with aggregate views, so the value is computed rather than copied.
  • Import in dependency order: parents, then children, then join rows.
Link translation
-- many-to-many: Airtable link field -> join table
create table project_contacts (
  project_id  uuid not null references projects(id) on delete cascade,
  contact_id  uuid not null references contacts(id) on delete cascade,
  airtable_link_src text,          -- original record id, kept for reconciliation
  primary key (project_id, contact_id)
);

-- rollup: Airtable rollup -> aggregate view
create view project_totals as
select p.id as project_id, count(t.id) as task_count, coalesce(sum(t.hours), 0) as hours
from projects p left join tasks t on t.project_id = p.id
group by p.id;

Failure modes

  • Treating every link as many-to-many, which loses the constraint that kept data clean.
  • Materialising rollups as static columns, which drift the moment the source changes.
  • Dropping the original record ID before reconciliation is signed off.

How it is verified

  • Row counts match per table and per relation.
  • For a sample of parent records, the set of linked child IDs matches exactly between systems.

Questions this pattern answers

What is preserving Airtable linked records in a migration?

Linked records are the part of an Airtable base with the most business meaning and the least schema rigour. They must be translated deliberately, not inferred by an importer.

How do you implement preserving linked records?

Classify each link field as one-to-many or many-to-many by inspecting actual data, not the field label. Give every table a stable surrogate key and keep the original Airtable record ID in an indexed column for the whole migration window. Translate one-to-many links to a foreign key; translate many-to-many links to a join table with its own primary key. Replace lookups with views or generated columns, and rollups with aggregate views, so the value is computed rather than copied. Import in dependency order: parents, then children, then join rows.

How is preserving linked records verified?

Row counts match per table and per relation. For a sample of parent records, the set of linked child IDs matches exactly between systems.

What usually goes wrong with preserving linked records?

Treating every link as many-to-many, which loses the constraint that kept data clean. Materialising rollups as static columns, which drift the moment the source changes. Dropping the original record ID before reconciliation is signed off.

Related patterns

Projects in this track

This page documents the method. Engagement scope and pricing live on TechTide AI.

Airtable Exit and Rescue at TechTide AI