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.
I use this reference example to explain the method and checks to try. It includes no client names, schemas, data, or reported results.
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.
-- 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
Inspecting Airtable dependencies →
The inventory includes forms, scripts, automations, and people’s work.
Mapping Airtable automations and scripts →
Each automation has a documented trigger and target.
Checking access after an Airtable migration →
Access checks compare what each person can read and change.
Comparing migrated data with Airtable →
Counts, checksums, and samples check the copied data.
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→© 2026 Alex Cinovoj · TechTide AI · Columbus, OH