Your Airtable export opens correctly in a spreadsheet. The row count looks plausible. Then a project in the new application has the wrong client, an attachment link stops working and an approval form still writes to the old base. Those failures have different causes. A reliable Airtable to PostgreSQL migration needs separate plans for records, relationships, files and application behavior.
The process below uses Airtable's documented export behavior and PostgreSQL 17 import semantics. The staging layout, relationship mapping and cutover checks are recommended engineering design. They are not a claim that either product automatically migrates the whole application for you.
Inventory the base before exporting
List every table, field, linked relationship and active workflow. Record who uses each view, which forms create records and which integrations update them. Include interfaces, automations and any reporting process that depends on calculated values. Give every retained behavior an owner and a target implementation.
Keep the data inventory separate from the workflow inventory. A table of projects might move cleanly while its approval process remains undocumented. Decide which behaviors will be rebuilt, retained temporarily or intentionally retired. The migration is incomplete until operators can perform the agreed work without accidental writes to the old system.
Export a complete view of each table
Airtable's ordinary CSV export is per table through a grid view on the web or desktop application. There is no ordinary full-base download as a single file. To capture all records in a table, export a view without filters. Make every required field visible because the export includes the field values visible in the view.
Create a migration manifest that records the table, chosen view, export time, expected row count and included fields. Retain the original files without editing them. Do not casually open and resave the only copy in a spreadsheet, where values may be reformatted before the import team sees them.
| Source item | Export boundary | Migration action |
|---|---|---|
| Table records | Chosen view and visible fields | Use unfiltered views and a field checklist |
| Comments and descriptions | Not included in CSV export | Agree a separate archive or exclusion |
| Attachment fields | Filenames and temporary URLs | Copy actual files and verify access |
| Application behavior | CSV is a data file | Rebuild and test the agreed workflows |
Airtable also excludes base guide content and data stored solely in extensions from CSV exports. Treat those exclusions as scope decisions. If an operator needs comments to understand a customer commitment, a table-only migration does not meet that need. Do not quietly redefine missing history as unnecessary.
Preserve identity before rebuilding links
Airtable provides the RECORD_ID() formula to return a record's unique identifier. Preserve that identifier in your extraction design, together with the base and table context. If adding a formula field is the chosen route, have an authorized owner approve the source change and include the field in the export view.
Keep a mapping from source identity to target identity. Names are useful for review but poor migration keys. Two clients can have the same name, and a project's display label can change. Reject ambiguous matches rather than linking to the first matching label.
Airtable linked records represent relationships between specific records and mirror that association in the linked table. A lookup can display information from the related record. In PostgreSQL, model each relationship deliberately. A many-to-many relationship usually needs a separate relationship table in the target design. Do not confuse a displayed lookup value with the relationship itself.
Capture attachment bytes, not just URLs
Airtable documents that attachment fields in CSV exports contain filenames and URLs. Those export URLs expire after a few hours. A saved CSV is therefore not a durable copy of its attachments. Schedule file capture as part of the extraction, not as cleanup after the database move.
For each file, retain the source record reference, original filename, captured storage location and verification result. Use checksums to compare downloaded bytes with the files you place in target storage. Keep failed downloads in an exception list. Test retrieval through the new application's permissions, not only through an administrator's storage console.
Load raw data into staging first
Create PostgreSQL staging tables before import. COPY loads into an existing table and maps input fields in order to an explicit column list. HEADER true skips the input header. It does not map arbitrary field names for you. Choose the file encoding explicitly and verify column order against the manifest.
For files on an operator's computer, psql's client-side copy facility reads from the client. A server-side COPY filename is interpreted from the database server's perspective. Choose a supported route for your environment instead of granting broad server file privileges just to load a local export.
Test blank values carefully. In PostgreSQL CSV mode, the default interpretation distinguishes an unquoted empty field as null from a quoted empty string. Inspect the actual Airtable output and agree the target meaning per field. Test embedded commas, quotes and line breaks with a real CSV parser.
Convert fields and validate meaning
Transform staging data into the agreed application tables with explicit rules for dates, numbers, selections and missing values. Keep rejected conversions tied to their source identity. PostgreSQL COPY invokes destination triggers and check constraints, so know which behavior will run before loading application tables.
Document whether a computed source value becomes a stored historical value, a target calculation or an application rule. Compare representative outputs with the source. Loading a displayed total does not define how that total should change when a user edits a related record later.
Validate row counts by table, unique source mappings, relationship pairs and attachment coverage. Then have operators check complete workflows. Open a client, inspect related projects, retrieve a file and submit a test update. Record each unexplained difference before approving cutover.
Plan the final change window
Do not assume LAST_MODIFIED_TIME() captures every dependency change. Airtable says automatic changes in computed fields are not directly reflected, and updates to fields inside a linked record do not change the referencing record's timestamp. Deletions also need an explicit reconciliation strategy in your migration design.
Choose a controlled write freeze or a change-capture design that covers the required scope. Reconcile the final dataset, switch forms and integrations, and monitor which system receives new writes. Retain a rollback plan that accounts for changes made after the switch. Avoid two active writers without a tested conflict policy.
How Remqa approaches Airtable migrations
Remqa's data migration work covers source inventory, mapping, test loads and operator validation. For Airtable, the scope should explicitly include relationships, files and the workflows behind the grid. Agree those boundaries before choosing an import tool.
Our Excel to PostgreSQL guide covers related CSV planning. Bring a base inventory and one representative workflow to a migration discussion. The useful first deliverable is a testable mapping and exception list, not a promise that a CSV replaces the application.