alexcinovoj.devby TechTide AI
Back to Airtable notes
Pattern · Airtable workflow examples

Preserving Airtable linked records

When migration is chosen, I map linked records deliberately using the actual relationships in the data. I preserve source record IDs and check links after import. An importer cannot reliably infer every business constraint from field labels.

Reference example

I use this reference example to explain the method and checks to try. It includes no client names, schemas, data, or reported results.

Short answer

How do I preserve Airtable linked records during migration?

When migration is chosen, I map linked records deliberately using the actual relationships in the data. I preserve source record IDs and check links after import.

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;

What can go wrong

  • Treating every link as many-to-many, which loses the constraint that kept data clean.
  • Copying rollups into static columns leaves them stale when source values change.
  • Removing source record IDs too early makes reconciliation harder.

Checks to try

  • 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

How do I preserve Airtable linked records during migration?

When migration is chosen, I map linked records deliberately using the actual relationships in the data. I preserve source record IDs and check links after import.

What steps does this method use?

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 can I check the result?

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 can go wrong with this approach?

Treating every link as many-to-many, which loses the constraint that kept data clean. Copying rollups into static columns leaves them stale when source values change. Removing source record IDs too early makes reconciliation harder.

Related patterns

Related projects

I explain this method here. The Airtable Rescue Decision Sprint can recommend staying, repairing, connecting tools, or migration. TechTide AI publishes current scope, prices, and terms.

Airtable Rescue Decision Sprint at TechTide AI