This topic describes how to migrate a complete Supabase project, including the database, storage objects, and Edge Functions, to AnalyticDB for PostgreSQL Supabase (AnalyticDB Supabase) using the supabase-cli migration tool.
Use cases
Migration paths
-
Migrate from Supabase Cloud to AnalyticDB Supabase.
-
Migrate from a self-hosted Supabase project to AnalyticDB Supabase.
-
Migrate between AnalyticDB Supabase projects.
Migration content
-
Database schema: Includes schemas, table structure, functions, and triggers.
-
Database data: Includes user data, auth data, and other system data.
-
PostgreSQL extensions: Automatically installs required plugins in the target project.
-
Storage objects: buckets and the files they contain.
-
Edge Functions: Function code and related configurations.
-
Roles and permissions: database user and permission settings.
Command syntax
Select the migration tool for your platform and run the following command to migrate.
./supabase-cli migrate-project [flags]
Required parameters
-
Source environment configuration
-
Supabase Cloud source configuration
--source-project-ref string # Source Project Ref (Required) --source-anon-key string # Source Anon Key (Required) --source-service-role-key string # Source Service Role Key (Required) -
Self-hosted Supabase project or AnalyticDB Supabase
--source-api-url string # Source API URL (Required) --source-anon-key string # Source Anon Key (Required) --source-service-role-key string # Source Service Role Key (Required) --source-database-url string # Source Database URL (Required, must be percent-encoded)
-
-
Target environment configuration
--target-api-url string # Target API URL (Required) --target-anon-key string # Target Anon Key (Required) --target-service-role-key string # Target Service Role Key (Required) --target-database-url string # Target Database URL (Required, must be percent-encoded)
Optional parameters
-
Supabase Cloud source configuration
--source-database-url string # Source Database URL (Optional, must be percent-encoded) -
Migration content
--include-data # Include database data (Default: true) --include-storage # Include storage objects (Default: true) --include-functions # Include Edge Functions (Default: true) --include-system-data # Include system module data (Default: true) -
Execution options
--use-local-exec # Use a local executor instead of a Docker container. Requires local installation of tools like pg_dump. --concurrency int # Number of concurrent operations (Default: 2) --dry-run # Preview the migration without executing it. --resume-from string # Resume from a specified step (database|storage|functions). -
Security options
ImportantWhen using the
--allow-truncateparameter, verify the source and target configurations to prevent accidental data deletion from the source database.--allow-truncate # Allow clearing table data (Default: false) --preserve-extra-tables # Preserve extra tables in the target database (Default: true)
Notes
-
Before migrating a production environment, fully validate the migration process in a staging environment.
-
Maintain a stable network connection during the migration.
-
Migrating a large database can be time-consuming. Plan your migration window accordingly.
-
Perform production environment migrations during off-peak hours.
Prerequisites
-
Ensure the following network connections are stable. For specific operations in AnalyticDB Supabase, see Modify a whitelist.
-
You can access the API and database of the source Supabase project.
-
You can access the API and database of the target environment.
-
The target database allows external connections.
-
-
Docker is installed and running.
Procedure
Step 1: Get project information and configure environment variables
-
Obtain the source configuration information.
For Supabase Cloud, obtain the following information from the project settings page.
-
Project Ref: A 20-character project ID.
-
Navigate to the Supabase console.
-
Click the source project and view its URL. For example, in the URL
https://supabase.com/dashboard/project/qeqfhfoebrtkbmwd****, the Project Ref is at the end:qeqfhfoebrtkbmwd****.
-
-
Anon Key: The anonymous key, which starts with
eyJ. -
Service Role Key: The service role key, which starts with
eyJ. This key must have permission to read all data. -
Database URL (Optional): The PostgreSQL connection string.
On the source project page, click connect, go to the Connection String tab, and select Transaction pooler for the Method.
-
-
Obtain the target AnalyticDB Supabase configuration information. For more information, see Obtain API Keys.
-
API URL: The full API address, such as
https://your-domain.supabase.opentrust.net. -
Anon Key: The anonymous key for the target environment.
-
Service Role Key: The service role key for the target environment. This key must have full administrative permissions.
-
Database URL: The PostgreSQL connection string. The target database user must have permissions to create tables, plugins, and other objects.
-
-
(Optional) To avoid exposing sensitive information on the command line, configure project information as environment variables.
-
Migrate from Supabase Cloud to AnalyticDB Supabase
# Create a configuration file cat > migration.env << 'EOF' SOURCE_PROJECT_REF="your-project-ref" SOURCE_ANON_KEY="eyJ..." SOURCE_SERVICE_ROLE_KEY="eyJ..." TARGET_API_URL="https://your-domain.supabase.opentrust.net" TARGET_ANON_KEY="eyJ..." TARGET_SERVICE_ROLE_KEY="eyJ..." TARGET_DATABASE_URL="postgres://postgres:password@{your-project-id}.supabase.opentrust.net:5432/postgres" EOF # Load the environment variables source migration.env -
Migrate from a self-hosted Supabase project or an AnalyticDB Supabase project to AnalyticDB Supabase
# Create a configuration file cat > migration.env << 'EOF' SOURCE_API_URL="http://localhost:54321" SOURCE_ANON_KEY="eyJ..." SOURCE_SERVICE_ROLE_KEY="eyJ..." SOURCE_DATABASE_URL="postgres://postgres:password@{your-project-id}.supabase.opentrust.net:5432/postgres" TARGET_API_URL="https://your-domain.supabase.opentrust.net" TARGET_ANON_KEY="eyJ..." TARGET_SERVICE_ROLE_KEY="eyJ..." TARGET_DATABASE_URL="postgres://postgres:password@{your-project-id}.supabase.opentrust.net:5432/postgres" EOF # Load the environment variables source migration.env
-
Step 2: Download the migration tool and log in
-
Download the supabase-cli tool for your operating system and architecture. In subsequent commands, use the filename of the downloaded tool instead of
supabase-cli. -
Run the following command and follow the prompts to complete the login.
./supabase-cli login
Step 3 (Optional): Preview migration
-
If you have not configured environment variables and your database password contains special characters, you must escape them.
-
If the Supabase Cloud database is inaccessible and you receive a "failed to connect to host=db.xxxx.supabase.co user=postgres database=postgres" error, set the
--source-database-urlparameter to the Transaction pooler address. To obtain this address, see Step 1: Get project information and configure environment variables.
-
Migrate from Supabase Cloud to AnalyticDB Supabase
./supabase-cli migrate-project \ --source-project-ref "$SOURCE_PROJECT_REF" \ --source-anon-key "$SOURCE_ANON_KEY" \ --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \ --target-api-url "$TARGET_API_URL" \ --target-anon-key "$TARGET_ANON_KEY" \ --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \ --target-database-url "$TARGET_DATABASE_URL" \ --dry-run -
Migrate from a self-hosted Supabase project or an AnalyticDB Supabase project to AnalyticDB Supabase
./supabase-cli migrate-project \ --source-hosted \ --source-api-url "$SOURCE_API_URL" \ --source-anon-key "$SOURCE_ANON_KEY" \ --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \ --source-database-url "$SOURCE_DATABASE_URL" \ --target-api-url "$TARGET_API_URL" \ --target-anon-key "$TARGET_ANON_KEY" \ --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \ --target-database-url "$TARGET_DATABASE_URL" \ --dry-run
Step 4: Migrate the Supabase project
-
If you have not configured environment variables and your database password contains special characters, you must escape them.
-
If the Supabase Cloud database is inaccessible and you receive a "failed to connect to host=db.xxxx.supabase.co user=postgres database=postgres" error, set the
--source-database-urlparameter to the Transaction pooler address. To obtain this address, see Step 1: Get project information and configure environment variables.
Complete project
-
Migrate from Supabase Cloud to AnalyticDB Supabase
./supabase-cli migrate-project \ --source-project-ref "$SOURCE_PROJECT_REF" \ --source-anon-key "$SOURCE_ANON_KEY" \ --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \ --target-api-url "$TARGET_API_URL" \ --target-anon-key "$TARGET_ANON_KEY" \ --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \ --target-database-url "$TARGET_DATABASE_URL" -
Migrate from a self-hosted Supabase project or an AnalyticDB Supabase project to AnalyticDB Supabase
./supabase-cli migrate-project \ --source-hosted \ --source-api-url "$SOURCE_API_URL" \ --source-anon-key "$SOURCE_ANON_KEY" \ --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \ --source-database-url "$SOURCE_DATABASE_URL" \ --target-api-url "$TARGET_API_URL" \ --target-anon-key "$TARGET_ANON_KEY" \ --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \ --target-database-url "$TARGET_DATABASE_URL"
Database only
Use the migrate-database subcommand to migrate only the database schema and data.
The following additional parameters are supported:
-
--include-data: Specifies whether to include data. -
--include-system-data: Specifies whether to include system data. -
--allow-truncate: Specifies whether to allow clearing table data. -
--preserve-extra-tables: Specifies whether to preserve extra tables.
The following examples show how to use this subcommand:
-
Migrate from Supabase Cloud to AnalyticDB Supabase
./supabase-cli migrate-project migrate-database \ --source-project-ref "$SOURCE_PROJECT_REF" \ --source-anon-key "$SOURCE_ANON_KEY" \ --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \ --target-api-url "$TARGET_API_URL" \ --target-anon-key "$TARGET_ANON_KEY" \ --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \ --target-database-url "$TARGET_DATABASE_URL" -
Migrate from a self-hosted Supabase project or an AnalyticDB Supabase project to AnalyticDB Supabase
./supabase-cli migrate-project migrate-database \ --source-hosted \ --source-api-url "$SOURCE_API_URL" \ --source-anon-key "$SOURCE_ANON_KEY" \ --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \ --source-database-url "$SOURCE_DATABASE_URL" \ --target-api-url "$TARGET_API_URL" \ --target-anon-key "$TARGET_ANON_KEY" \ --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \ --target-database-url "$TARGET_DATABASE_URL"
Storage only
Use the migrate-storage subcommand to migrate only storage buckets and objects.
-
Migrate from Supabase Cloud to AnalyticDB Supabase
./supabase-cli migrate-project migrate-storage \ --source-project-ref "$SOURCE_PROJECT_REF" \ --source-anon-key "$SOURCE_ANON_KEY" \ --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \ --target-api-url "$TARGET_API_URL" \ --target-anon-key "$TARGET_ANON_KEY" \ --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \ --target-database-url "$TARGET_DATABASE_URL" -
Migrate from a self-hosted Supabase project or an AnalyticDB Supabase project to AnalyticDB Supabase
./supabase-cli migrate-project migrate-storage \ --source-hosted \ --source-api-url "$SOURCE_API_URL" \ --source-anon-key "$SOURCE_ANON_KEY" \ --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \ --source-database-url "$SOURCE_DATABASE_URL" \ --target-api-url "$TARGET_API_URL" \ --target-anon-key "$TARGET_ANON_KEY" \ --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \ --target-database-url "$TARGET_DATABASE_URL"
Functions only
Use the migrate-functions subcommand or the functions-cli tool to migrate only Edge Functions.
-
Migrate from Supabase Cloud to AnalyticDB Supabase
./supabase-cli migrate-project migrate-functions \ --source-project-ref "$SOURCE_PROJECT_REF" \ --source-anon-key "$SOURCE_ANON_KEY" \ --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \ --target-api-url "$TARGET_API_URL" \ --target-anon-key "$TARGET_ANON_KEY" \ --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \ --target-database-url "$TARGET_DATABASE_URL" -
Migrate from a self-hosted Supabase project or an AnalyticDB Supabase project to AnalyticDB Supabase
./supabase-cli migrate-project migrate-functions \ --source-hosted \ --source-api-url "$SOURCE_API_URL" \ --source-anon-key "$SOURCE_ANON_KEY" \ --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \ --source-database-url "$SOURCE_DATABASE_URL" \ --target-api-url "$TARGET_API_URL" \ --target-anon-key "$TARGET_ANON_KEY" \ --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \ --target-database-url "$TARGET_DATABASE_URL"
FAQ
'Connection refused' error
Run the following command to check the network connection.
# Check the network connection
ping db.your-project-ref.supabase.co
# Check the Database URL format
# Correct format: postgres://postgres:password@host:port/database
'Permission denied' error
-
Ensure you are using the Service Role Key, not the Anon Key.
-
Ensure the key has sufficient permissions. For requirements, see Prerequisites.
-
Confirm that the target database user has administrative permissions.
Plugin not available error
Install the missing plugin in the target database, or remove the unnecessary plugin from the source database.
Sequence conflict error
Use the following command:
# Use a safer table cleanup policy
supabase migrate-project ... --preserve-extra-tables=true --allow-truncate=true
Special characters in connection strings
We recommend using environment variables for project information. If you pass the connection string directly, you must escape any special characters as follows:
! : %21
@ : %40
# : %23
$ : %24
% : %25
^ : %5e
& : %26
* : %2a
( : %28
) : %29
_ : %5f
+ : %2b
= : %3d