simplify and shorten

Run pnpm format
This commit is contained in:
PLyn committed 2025-08-25 10:09:30 -05:00
1 parent 87f1294971
commit 444795edfb
1 file changed
+102 -131
@@ -7,26 +7,23 @@ If you are on a Paid Plan and have physical backups enabled, you should instead
to another project feature](/docs/guides/platform/clone-project).
### Caveats
- Project migration is primarily for changing regions or upgrading to new major versions of the platform in some scenarios. If you need to move your project to a different organization without touching the infrastructure, see [project transfers](/docs/guides/platform/project-transfer).
- **Project migration only migrates the Postgres database** which means that everything that is stored in your database will be migrated. However, here is a non-exhaustive list of things to re-configure:
- Edge Functions
- Auth Settings and API keys
- Realtime settings
- Database extensions and settings
- Read Replicas
- Storage objects in S3 buckets ([Migration guide](/docs/guides/platform/migrating-within-supabase#migrate-storage))
- If you need to move your project to a different organization without touching the infrastructure, see [project transfers](/docs/guides/platform/project-transfer).
### Before you begin
- **Project migration only migrates the Postgres database** and anything else will need to be re-configured.
### Pre-Migration Checklist
<Accordion
type="default"
openBehaviour="multiple"
chevronAlign="right"
justified
className="text-foreground-light mt-8 mb-6"
<Accordion
type="default"
openBehaviour="multiple"
chevronAlign="right"
justified
size="medium"
className="text-foreground-light mt-8 mb-6"
>
<div className="border-b mt-3 pb-3">
<AccordionItem
header={<span className="text-foreground">Install postgres and psql</span>}
@@ -37,15 +34,16 @@ to another project feature](/docs/guides/platform/clone-project).
</div>
</Accordion>
Here are some items to note down your changes made to re-configure in the new project:
- Auth Settings and API keys
- Edge Functions
- Read Replicas
- Realtime configuration
### Project backup
If you already have a project backup, skip to the Restore project step. You can get the project backup file from sources such as:
- (For Pro Plan and higher) [Database backups page](https://supabase.com/dashboard/project/_/database/backups/scheduled)
- 90 day paused projects page
If you do not have a project backup yet, you can do a manual database dump following the guide below:
If you already have the database backup, skip to the Restore project step.
<Accordion
type="default"
@@ -75,22 +73,9 @@ If you do not have a project backup yet, you can do a manual database dump follo
<StepHikeCompact.Step step={3}>
<StepHikeCompact.Details title="Get the new database connection string" fullWidth>
On your project dashboard, click [Connect](https://supabase.com/dashboard/project/_?showConnect=true).
<Admonition type="note">
Use the Session pooler connection string by default. If your ISP supports IPv6 or you have the IPv4 add-on enabled, use the direct connection string.
</Admonition>
Session pooler connection string:
Get your Session pooler connection string from your [Connect page](https://supabase.com/dashboard/project/_?showConnect=true). Example connection string:
```bash
postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@aws-0-us-east-1.pooler.supabase.com:5432/postgres
```
Direct connection string:
```bash
postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@db.[PROJECT-REF].supabase.com:5432/postgres
postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@aws-0-[PROJECT-REGION].pooler.supabase.com:5432/postgres
```
</StepHikeCompact.Details>
@@ -98,10 +83,7 @@ If you do not have a project backup yet, you can do a manual database dump follo
<StepHikeCompact.Step step={4}>
<StepHikeCompact.Details title="Get the database password" fullWidth>
Reset the password in the [Database Settings](/dashboard/project/_/settings/database).
Replace ```[YOUR-PASSWORD]``` in the connection string with the database password.
Reset and copy the password in the [Database Settings](/dashboard/project/_/settings/database). Replace ```[YOUR-PASSWORD]``` in step 3 with the database password.
</StepHikeCompact.Details>
</StepHikeCompact.Step>
@@ -112,13 +94,7 @@ If you do not have a project backup yet, you can do a manual database dump follo
```bash
supabase db dump --db-url [CONNECTION_STRING] -f roles.sql --role-only
```
```bash
supabase db dump --db-url [CONNECTION_STRING] -f schema.sql
```
```bash
supabase db dump --db-url [CONNECTION_STRING] -f data.sql --use-copy --data-only
```
</StepHikeCompact.Details>
@@ -129,46 +105,23 @@ If you do not have a project backup yet, you can do a manual database dump follo
</div>
</Accordion>
### Restore project backup
<StepHikeCompact>
<StepHikeCompact.Step step={1}>
<StepHikeCompact.Details title="Create project" fullWidth>
Create a [new project](https://database.new)
<StepHikeCompact.Details title="Create and configure new project" fullWidth>
Create a [new project](https://database.new). In the new project:
- If Webhooks were used in the old database, enable [Database Webhooks](/dashboard/project/_/database/hooks).
- If any non-default extensions were used in the old database, enable the [Extensions](/dashboard/project/_/database/extensions).
</StepHikeCompact.Details>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={2}>
<StepHikeCompact.Details title="Configure newly created project" fullWidth>
In the new project:
- If Webhooks were used in the old database, enable [Database Webhooks](/dashboard/project/_/database/hooks).
- If any non-default extensions were used in the old database, enable the [Extensions](/dashboard/project/_/database/extensions).
- If Replication for Realtime was used in the old database, enable [Publication](/dashboard/project/_/database/publications) on the tables necessary
</StepHikeCompact.Details>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={3}>
<StepHikeCompact.Details title="Get the new database connection string" fullWidth>
Go to the [project page](/dashboard/project/_/) and click the "**Connect**" button at the top of the page for the connection string.
<Admonition type="note">
Use the Session pooler connection string by default. If your ISP supports IPv6, use the direct connection string.
</Admonition>
Session pooler connection string:
```bash
postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@aws-0-us-east-1.pooler.supabase.com:5432/postgres
```
Direct connection string:
```bash
postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@db.[PROJECT-REF].supabase.com:5432/postgres
```
<StepHikeCompact.Details title="Get the new Session pooler connection string" fullWidth>
Get your Session pooler connection string from your [Connect page](https://supabase.com/dashboard/project/_?showConnect=true). Example connection string:
```bash
postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@aws-0-[PROJECT-REGION].pooler.supabase.com:5432/postgres
```
</StepHikeCompact.Details>
</StepHikeCompact.Step>
@@ -176,16 +129,13 @@ If you do not have a project backup yet, you can do a manual database dump follo
<StepHikeCompact.Step step={4}>
<StepHikeCompact.Details title="Get the database password" fullWidth>
Reset the password in the [project connect page](/dashboard/project/_?showConnect=true).
Replace ```[YOUR-PASSWORD]``` in the connection string with the database password.
Reset and copy the password in the [Database Settings](/dashboard/project/_/settings/database). Replace ```[YOUR-PASSWORD]``` in step 2 with the database password.
</StepHikeCompact.Details>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={5}>
<StepHikeCompact.Details title="Restore your Project with the CLI" fullWidth>
Run these commands after replacing ```[CONNECTION_STRING]``` with your connection string from the previous steps:
Replace ```[CONNECTION_STRING]``` with your connection string from the previous steps and run the following command:
```bash
psql \
@@ -198,71 +148,92 @@ If you do not have a project backup yet, you can do a manual database dump follo
--dbname [CONNECTION_STRING]
```
</StepHikeCompact.Details>
</StepHikeCompact.Step>
</StepHikeCompact>
### Migrate Storage
The new project has the old project's Storage buckets, but the Storage objects need to be migrated manually.
If you have your storage objects locally (eg 90 day paused projects), migrate the storage objects to the new project using this [google colab script](https://colab.research.google.com/github/PLyn/supabase-storage-migrate/blob/main/Supabase_Storage_migration.ipynb).
The new project has the old project's Storage buckets, but the Storage objects need to be migrated manually. If you have your storage objects locally (eg 90 day paused projects), migrate the storage objects to the new project using this [google colab script](https://colab.research.google.com/github/PLyn/supabase-storage-migrate/blob/main/Supabase_Storage_migration.ipynb).
If the old project is still active, use this script to move storage objects from one project to another:
```js
// npm install @supabase/supabase-js@1
const { createClient } = require('@supabase/supabase-js')
<Accordion
type="default"
openBehaviour="multiple"
chevronAlign="right"
justified
size="medium"
className="text-foreground-light mt-8 mb-6"
>
<div className="border-b mt-3 pb-3">
<AccordionItem
header={<span className="text-foreground">Storage migration script</span>}
id="backup-project"
>
```js
// npm install @supabase/supabase-js@1
const { createClient } = require('@supabase/supabase-js')
const OLD_PROJECT_URL = 'https://xxx.supabase.co'
const OLD_PROJECT_SERVICE_KEY = 'old-project-service-key-xxx'
const OLD_PROJECT_URL = 'https://xxx.supabase.co'
const OLD_PROJECT_SERVICE_KEY = 'old-project-service-key-xxx'
const NEW_PROJECT_URL = 'https://yyy.supabase.co'
const NEW_PROJECT_SERVICE_KEY = 'new-project-service-key-yyy'
const NEW_PROJECT_URL = 'https://yyy.supabase.co'
const NEW_PROJECT_SERVICE_KEY = 'new-project-service-key-yyy'
;(async () => {
const oldSupabaseRestClient = createClient(OLD_PROJECT_URL, OLD_PROJECT_SERVICE_KEY, {
schema: 'storage',
})
const oldSupabaseClient = createClient(OLD_PROJECT_URL, OLD_PROJECT_SERVICE_KEY)
const newSupabaseClient = createClient(NEW_PROJECT_URL, NEW_PROJECT_SERVICE_KEY)
;(async () => {
const oldSupabaseRestClient = createClient(OLD_PROJECT_URL, OLD_PROJECT_SERVICE_KEY, {
schema: 'storage',
})
const oldSupabaseClient = createClient(OLD_PROJECT_URL, OLD_PROJECT_SERVICE_KEY)
const newSupabaseClient = createClient(NEW_PROJECT_URL, NEW_PROJECT_SERVICE_KEY)
// make sure you update max_rows in postgrest settings if you have a lot of objects
// or paginate here
const { data: oldObjects, error } = await oldSupabaseRestClient.from('objects').select()
if (error) {
console.log('error getting objects from old bucket')
throw error
}
// make sure you update max_rows in postgrest settings if you have a lot of objects
// or paginate here
const { data: oldObjects, error } = await oldSupabaseRestClient.from('objects').select()
if (error) {
console.log('error getting objects from old bucket')
throw error
}
for (const objectData of oldObjects) {
console.log(`moving ${objectData.id}`)
try {
const { data, error: downloadObjectError } = await oldSupabaseClient.storage
for (const objectData of oldObjects) {
console.log(`moving ${objectData.id}`)
try {
const { data, error: downloadObjectError } = await oldSupabaseClient.storage
.from(objectData.bucket_id)
.download(objectData.name)
if (downloadObjectError) {
if (downloadObjectError) {
throw downloadObjectError
}
}
const { _, error: uploadObjectError } = await newSupabaseClient.storage
.from(objectData.bucket_id)
.upload(objectData.name, data, {
upsert: true,
contentType: objectData.metadata.mimetype,
cacheControl: objectData.metadata.cacheControl,
})
if (uploadObjectError) {
throw uploadObjectError
}
} catch (err) {
console.log('error moving ', objectData)
console.log(err)
}
}
})()
```
const { _, error: uploadObjectError } = await newSupabaseClient.storage
.from(objectData.bucket_id)
.upload(objectData.name, data, {
upsert: true,
contentType: objectData.metadata.mimetype,
cacheControl: objectData.metadata.cacheControl,
})
if (uploadObjectError) {
throw uploadObjectError
}
} catch (err) {
console.log('error moving ', objectData)
console.log(err)
}
}
})()
```
</AccordionItem>
</div>
</Accordion>
### Troubleshooting notes
- If you have created any custom roles with login attribute, you have to manually set their passwords in the new project.
- If you get this error: **"...received invalid response to GSSAPI negotiation..."**. You are likely using psql and Postgres version 15 or lower. Install the latest version to resolve this issue.
- If you get this error: **"...received invalid response to GSSAPI negotiation..."**. You are likely using psql and Postgres version 15 or lower. Install the latest version to resolve this issue.
```
```