Migrate tables without primary keys

This page explains how to migrate Oracle tables that don't have primary keys.

Automatic primary key generation overview

Tables without primary keys don't promise consistent replication. Database Migration Service only migrates tables that have primary keys. If your source database includes tables that don't have primary keys, Database Migration Service can handle that in the following ways:

  • When you convert your source code and schema, Database Migration Service can automatically create any missing primary keys by adding ROWID columns in the destination tables. This automated process requires that your source tables:
    • Don't already have primary keys.
    • Don't have a UNIQUE constraint with no nullable columns.
    • Don't have a UNIQUE index with no nullable columns.
    If your tables don't meet these requirements, you need to manually add missing primary keys to the tables in the converted PostgreSQL schema.
  • In legacy conversion workspaces, Database Migration Service doesn't automatically create primary keys. If you use a legacy conversion workspace, you need to manually add missing primary keys to the tables in the converted PostgreSQL schema.

Add missing primary keys manually

To migrate Oracle tables without primary keys, do the following:

  1. Use a conversion workspace to convert your source code and schema.
  2. Connect to your destination Cloud SQL instance with a SQL client. You can use the following methods:
    • psql client. You can use this method to connect to your instance private IP, but it might require that you create a Compute Engine virtual machine.
    • gcloud sql connect command. This command works only for Cloud SQL instances that have a public IP address enabled.
  3. Create the missing primary key constraints for your tables. For more information about primary keys, see Primary Keys in the PostgreSQL documentation.

    You can also expand the following sections to see sample SQL commands:

    Create primary keys using existing columns

    Your table might already have a logical primary key based on a column or a combination of columns. For example, there might be columns with a unique constraint or index configured. Use these columns to generate a new primary key for tables in your source database. For example:

    ALTER TABLE TABLE_NAME
    ADD PRIMARY KEY (COLUMN_NAME);

    Replace the following:

    • TABLE_NAME with the name of your table that doesn't have a primary key.
    • COLUMN_NAME with the name of a column with unique constraint or index that you can use as the primary key.

    Create a primary key using all columns

    If you don't have a pre-existing constraint that could serve as a primary key, create primary keys using all columns of the table. Make sure that you don't exceed the maximum length of the primary key allowed by your PostgreSQL instance.

    When you create a composite primary key this way, you need to explicitly list all column names you want to use. It's not possible to use a statement to retrieve all column names for this purpose. For example:

    ALTER TABLE TABLE_NAME
    ADD PRIMARY KEY (COLUMN_NAME_1, COLUMN_NAME_2, COLUMN_NAME_3, ...);

    Replace the following:

    • TABLE_NAME with the name of your table that doesn't have a primary key.
    • COLUMN_NAME_1, COLUMN_NAME_2 etc. with the names of columns you want to use to create the primary key.

    Create a unique constraint with the ROWID pseudocolumn

    Oracle databases use the ROWID pseudocolumn to store the location of each row in a table. To migrate Oracle tables that don't have primary keys, you can add a ROWID column in the destination PostgreSQL database. Database Migration Service populates the column with the corresponding numeric values from the source Oracle ROWID pseudocolumn.

    To add the column and to set it as the primary key, run the following:

    ALTER TABLE TABLE_NAME ADD COLUMN rowid numeric(33,0) NOT NULL;
    CREATE SEQUENCE TABLE_NAME_rowid_seq INCREMENT BY -1 START WITH -1 OWNED BY TABLE_NAME.rowid;
    ALTER TABLE TABLE_NAME ALTER COLUMN rowid SET DEFAULT nextval('TABLE_NAME_rowid_seq');
    ALTER TABLE TABLE_NAME ADD CONSTRAINT CONSTRAINT_DISPLAY_NAME PRIMARY KEY (rowid);

    Replace the following:

    • TABLE_NAME with the name of the table in which you want to add the column.
    • CONSTRAINT_DISPLAY_NAME with the identifier for the PRIMARY KEY constraint.

What's next