u/Delicious_Bird_2847

finally cracked full airtable to supabase migration (formulas, rollups, linked records, attachments)

finally cracked full airtable to supabase migration (formulas, rollups, linked records, attachments)

migrating off airtable into postgres sounds like it should be a solved problem by now. it really isn't, and the reasons why are more interesting than i expected when i started.

the trap most people fall into:

first instinct is usually csv export. doesn't work. linked records come out as comma-separated record ids text, not relationships. you've moved data, not structure.

second instinct is a python script against the airtable api. this gets you about 60% of the way and then collapses under its own weight. you end up having to:

  • detect which links are one-to-many vs many-to-many and build junction tables for the latter
  • figure out insert order so foreign keys actually resolve instead of erroring out
  • map airtable field types to postgres equivalents (some have no clean mapping)
  • pull attachments before their urls expire
  • do something reasonable with formulas, rollups, and lookups

why sync tools aren't actually a migration

whalesync and sequin both work and i don't want to take anything away from them they're solid at what they do. but the thing that took me a while to internalize is that they sync computed values, not the logic that produced them. so postgres ends up holding a number that airtable calculated. modify a linked record on the postgres side and nothing recalculates. only airtable still knows the formula. the new value syncs back over from airtable.

practical implication: you can't actually cancel airtable. you're locked into paying for it forever, or your "migrated" data goes stale the moment it changes.

the post-migration problem that surprised me

once everything lands in postgres with proper junction tables and foreign keys, the schema is correct but the experience of working with it is much worse than airtable. one airtable row that showed you names, computed totals, and linked record titles becomes a 3-4 table join in sql. correct, but you've lost the at-a-glance view your team has been using for years.

what worked for me: generating a layer of postgres views during the migration that recompose the table back into something readable. linked record names appear inline, rollups show as computed columns, lookups resolve. the underlying schema stays normalized, the views just give you a familiar way to look at it.

formulas were the biggest time sink

airtable's formula language isn't sql and has enough quirks that direct translation isn't always possible. i kept grinding on it and got to roughly 80% coverage on the common patterns text functions, date arithmetic, math, logical operators, most if/switch logic, the typical record-level stuff. these map cleanly to postgres expressions or generated columns. the last 20% is genuinely airtable-specific behavior that needs a human call. but 80% means you're reviewing and editing, not rewriting.

what i'm building

atmigrator handles this end-to-end as a one-shot migration. formulas and rollups become real postgres logic. linked records become proper foreign keys with junction tables where needed. attachments get pulled and rehosted before urls expire. views get generated on top so the destination doesn't feel alien.

anyone who's migrated off airtable into supabase or any postgres host, how did you handle the formula side specifically? rewrite by hand, accept static values from sync, or something else? trying to understand what people actually need.

u/Delicious_Bird_2847 — 5 days ago

After months of working on it, i finally cracked full airtable migration formulas, rollups, linked records, attachments all preserved

spent the last few months trying to migrate a airtable base into postgres and i've come out the other side with strong opinions. moving the rows is the easy part. the moment your base has linked records across 4+ tables, lookups pulling from those links, rollups summing things up, and formulas calculating from various fields and attachments with expiring urls then things get difficult.

csv export turns linked records into strings of comma-separated record ids. useless. you can't import that into postgres and call it relational data, you've just moved text around.

the obvious next step is some kind of python script against the airtable api. this works for a weekend, until you realize you need to figure out which links are many-to-many, build junction tables, insert records in the right order so the foreign keys actually resolve, handle the airtable types that don't have clean postgres equivalents, deal with attachments before their urls expire (yes they expire and your database will be full of dead links if you don't catch this), and somehow translate formula fields into something that still works after the data lands.

then you look at sync tools. whalesync and sequin are the two real options and they do work but here's what i didn't realize at first: formula, rollup, and lookup fields sync as values only, not as logic. so postgres holds a number airtable calculated. change anything on the postgres side and postgres can't recalculate, only airtable can, then it syncs the new value back over. if you wanted to actually leave airtable, you can't. you're paying for sync forever. atmigrator goes the other way on this. formulas, rollups, and lookups get rebuilt as actual postgres logic (generated columns, expressions, real relationships) so they keep working after airtable is gone.

the after-migration problem is the one i didn't see coming. once your data is in normalized postgres tables with junction tables for the many-to-many links, every query that used to be "open the table and look" now requires joining 3-4 tables. it's correct, it's proper sql, but you've lost the readable single-row view of your data you'd been working with for years. we solved this by generating a layer of postgres views during the migration that stitch everything back together. linked record names show up inline, rollups and lookups appear as computed columns. familiar entry point on top of a clean schema underneath. this is baked into atmigrator now, the views get generated automatically so you don't open postgres on day one and panic or spend hours in writing queries or hiring someone for that.

formulas i kept grinding on until i had about 80% of common airtable formulas mapping to actual postgres expressions. text, dates, math, logical operators, most of the if/switch patterns. the remaining 20% is the genuinely airtable-specific stuff that needs human judgment. but 80% means you're editing, not rewriting.

attachments are their own mess. airtable urls expire, so they have to be pulled and rehosted as part of the migration itself, not after.

To solved all the problem i faced and probably you facing, we built atmigrator.com a one-shot migration tool(no ongoing sync, no subscription).

anyone else gone through this? how bad was the formula situation for you specifically?

https://preview.redd.it/bcw20zzf2p1h1.png?width=1080&format=png&auto=webp&s=8771ef1a46d316a6d06cc45aa5249562a3bfe35e

reddit.com
u/Delicious_Bird_2847 — 5 days ago