Best Practices for Multiple Teams Deploying to the Same Database (Oracle)

This document discusses use-cases when there are multiple teams that deploy to the same database. We will discuss the following two use-cases in this scenario:

  1. Each team has one or more dedicated schema(s) in the same database
  2. Multiple teams write to one or more shared schema in the same database

Use-case 1: Each team has one or more dedicated schema in the same database

This is a common use-case for applications that integrate multiple subsystems. Multiple teams, each with their own Git repository, deploy database changes into their own dedicated schemas in the same database .

Team Schema
Team 1 SchemaA
Team 2 SchemaB
Team 3 SchemaC
Team4 SchemaD

Structuring Git repository

Each team will dedicate a directory in their repository for database changes. In this directory, they can manage all their scripts along with the changelog.xml file. The team can also create a directory for their schema.

In the case of a team deploying to multiple schemas, they could organize their repository where they have a subdirectory for each schema.

The team needs a main changelog file which can control the flow of all changes to all schemas.

See the section "Deploying with Liquibase" later in this document for sample scripts.

Use-case 2: Multiple teams write to one or more shared schemas in the same database

In this use-case, multiple teams, each with their own Git repository, deploy database changes to one or more shared schemas. This use-case is common for legacy applications that have added subsystems over time or other complex application architectures.

Team Schema
Team 1 SchemaA, SchemaB, SchemaC
Team 2
Team 3
Team 4
  1. You will use a single URL and credentials to connect to all databases. This requires that you use a single service account which has permissions to multiple databases.
  2. Within SQL scripts, each object would need to be fully qualified with database name, schema name and object name. This is a requirements because of the single service account used to deploy to multiple databases.
  3. Liquibase tracking tables (DATABASECHANGELOG and DATABASECHANGELOGLOCK) will be created only in one database that is specified in the URL. Deployments to multiple databases will be tracked by a single DATABASECHANGELOG tracking table in the database specified in the URL.

Note: It is important to understand that teams must communicate with each other about their database changes going into shared schemas. Database changes often have dependencies, and these changes need to be coordinated so that they are deployed in the correct order.

Structuring Git repository

When multiple teams share common schemas, it is not possible to use each team's own application repository. This use case requires setting up a dedicated SQL repository for shared schemas.

The team needs a main changelog file that can control the flow of all changes to all schemas.

See the section "Deploying with Liquibase" later in this document for sample scripts.

Sample mainChangelog.xml

Here is a sample mainChangelog.xml file which can be used in a multi-schema repository:


<databaseChangeLog
    xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:pro="http://www.liquibase.org/xml/ns/pro"
    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
        http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.6.xsd
        http://www.liquibase.org/xml/ns/pro
        http://www.liquibase.org/xml/ns/pro/liquibase-pro-4.6.xsd ">

    <include file="schemaA/changelog.xml" context="schemaA"/>
    <include file="schemaB/changelog.xml" context="schemaB"/>
    <include file="schemaC/changelog.xml" context="schemaC"/>

</databaseChangeLog>

Deploying with Liquibase

The basic script for deploying with Liquibase using a single service account to deploy to multiple shared schemas looks like this:

# add liquibase path to the environment variable
export PATH=<Path to Liquibase>:${PATH}

# git clone or retrieve a versioned artifact
git clone <GIT URL to the repo> 

cd <Repo>/sql_code

# run the "status" command
liquibase status --changelog-file=masterChangelog.xml \
          --url=<Database URL> \
          --username=<username> \
          --password=<password> \
          -–verbose

# run the "update" command
liquibase update --changelog-file=masterChangelog.xml \
          --url=<Database URL> \
          --username=<username> \
          --password=<password>

# run the "history" command
liquibase history --changelog-file=masterChangelog.xml \
          --url=<Database URL> \
          --username=<username> \
          --password=<password>

The script for deploying with Liquibase using proxy users to deploy to one schema at a time looks like this. This is for the Oracle use case:

# add liquibase path to the environment variable
export PATH=<Path to Liquibase>:${PATH}

# git clone or retrieve a versioned artifact
git clone <GIT URL to the repo>
cd <Repo>/sql_code
LBSCHEMANAMES="${1:-"HR OC OE SH"}"

for LBSCHEMA in $LBSCHEMANAMES
do

# run the "status" command
liquibase status --changelog-file=masterChangelog.xml \
          --url=<Database URL> \
          --username=<username> \
          --password=<password> \
          --default-schema-name=${LBSCHEMA} \
          –-verbose

# run the "update" command
liquibase update –-changelog-file=masterChangelog.xml \
          --url=<Database URL> \
          --username=<username> \
          --password=<password> \
          --default-schema-name=${LBSCHEMA}

# run the "history" command
liquibase history --changelog-file=masterChangelog.xml \
          --url=<Database URL> \
          --username=<username> \
          --password=<password> \
          --default-schema-name=${LBSCHEMA}
done

Liquibase automatically creates DATABASECHANGELOG and DATABASECHANGELOGLOCK tables (also called DBCL tables) for tracking deployments. These tables are created in the default schema for the user connecting to the database.

If you want your DBCL tables to be created in another schema, e.g., a dedicated schema for Liquibase tracking only, then you can use --liquibase-schema-name=<schema> to indicate your specific schema. You need to make sure that the service account allows creating DBCL tables in this schema, and allows querying these tables.

  • --liquibase-schema-name=<schema>
    • The parameter specifies the schema to use for the creation of Liquibase objects, like the DATABASECHANGELOG and DATABASECHANGELOGLOCK tracking tables.
  • --default-schema-name=<schema>
    • The parameter specifies the default schema name to use for the database connection.