@@ -2,7 +2,7 @@
3[](https://github.com/fabianlindfors/reshape/actions/workflows/test.yaml) [](https://github.com/fabianlindfors/reshape/releases)
3[](https://github.com/fabianlindfors/reshape/actions/workflows/test.yaml) [](https://github.com/fabianlindfors/reshape/releases)
5−> Also check out [ReshapeDB](https://reshapedb.com), a new database built from the ground up to make zero-downtime schema and data migrations as simple and safe as possible
5+> Also check out [ReshapeDB](https://reshapedb.com), a new database built from the ground up to make zero-downtime schema and data migrations as simple and safe as possible. If you'd like to chat about it, please [reach out](contact@reshapedb.com)!
7Reshape is an easy-to-use, zero-downtime schema migration tool for Postgres. It automatically handles complex migrations that would normally require downtime or manual multi-step changes. During a migration, Reshape ensures both the old and new schema are available at the same time, allowing you to gradually roll out your application. It will also perform all changes without excessive locking, avoiding downtime caused by blocking other queries. For a more thorough introduction to Reshape, check out the [introductory blog post](https://fabianlindfors.se/blog/schema-migrations-in-postgres-using-reshape/).
7Reshape is an easy-to-use, zero-downtime schema migration tool for Postgres. It automatically handles complex migrations that would normally require downtime or manual multi-step changes. During a migration, Reshape ensures both the old and new schema are available at the same time, allowing you to gradually roll out your application. It will also perform all changes without excessive locking, avoiding downtime caused by blocking other queries. For a more thorough introduction to Reshape, check out the [introductory blog post](https://fabianlindfors.se/blog/schema-migrations-in-postgres-using-reshape/).
@@ -243,6 +243,7 @@ primary_key = ["user_id"]
243 type = "TEXT"
243 type = "TEXT"
245 # Backfill from `users` table and copy `users.email` to `user_email` column
245 # Backfill from `users` table and copy `users.email` to `user_email` column
246+ # This will perform an upsert based on the primary key to avoid duplicate rows
246 [actions.up]
247 [actions.up]
247 table = "users"
248 table = "users"
248 values = { user_id = "id", user_email = "email" }
249 values = { user_id = "id", user_email = "email" }
@@ -621,7 +622,7 @@ abort = """
622### Complex changes across tables
623### Complex changes across tables
624−The `up` and `down` options available for many actions can also perform more complex changes that span tables.
625+The `up` and `down` options available when creating tables, adding columns and removing columns can also perform more complex changes that span tables.
626_Example: move `email` column from `users` to `profiles` table_
627_Example: move `email` column from `users` to `profiles` table_
@@ -653,6 +654,57 @@ table = "profiles"
653 where = "user_id = id"
654 where = "user_id = id"
657+_Example: turn a 1:N relationship between `users` and `accounts` into N:M and change the format of the associated `role`_
660+# Add `user_account_connections` as a junction table
662+type = "create_table"
663+name = "user_account_connections"
664+primary_key = ["account_id", "user_id"]
674+ # `role` is currently stored directly on the `users` table but is part of the relationship
679+ # Backfill the new table from `users` and uppercase the `role`
682+ values = { user_id = "id", account_id = "account_id", role = "UPPER(account_role)" }
683+ where = "user_id = id"
686+type = "remove_column"
688+column = "account_id"
690+ # When `user_account_connections` is updated, we write the `account_id` back to `users`
692+ table = "user_account_connections"
693+ value = "account_id"
694+ where = "id = user_id"
697+type = "remove_column"
699+column = "account_role"
701+ # When `user_account_connections` is updated, we write the lowercase role back to `users`
703+ table = "user_account_connections"
704+ value = "LOWER(role)"
705+ where = "id = user_id"
656## Commands and options
708## Commands and options
658### `reshape migration start`
710### `reshape migration start`