# Best Approach for Database Migrations in Concrete CMS?

**URL:** https://forums.concretecms.org/t/best-approach-for-database-migrations-in-concrete-cms/8471
**Category:** Developing with Concrete
**Created:** [November 28, 2024, 6:59pm UTC](https://forums.concretecms.org/t/best-approach-for-database-migrations-in-concrete-cms/8471 "2024-11-28T18:59:42Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![williamharry](https://forums.concretecms.org/user_avatar/forums.concretecms.org/williamharry/32/3495_2.png) [@williamharry](https://forums.concretecms.org/u/williamharry)
#### Post date: [November 28, 2024, 6:59pm UTC](https://forums.concretecms.org/t/best-approach-for-database-migrations-in-concrete-cms/8471/1 "2024-11-28T18:59:42Z")

</div>

I’m looking for the best practices for handling database migrations in Concrete CMS. Is there a recommended method for managing schema changes between development and production environments? Should I rely on core tools, or are there third-party packages that streamline this process? Any advice on avoiding downtime and ensuring data integrity during migrations?

---

<div class="post-metadata">

### Author: ![Myq](https://forums.concretecms.org/user_avatar/forums.concretecms.org/myq/32/4281_2.png) [@Myq](https://forums.concretecms.org/u/Myq)
#### Post date: [December 2, 2024, 11:51pm UTC](https://forums.concretecms.org/t/best-approach-for-database-migrations-in-concrete-cms/8471/2 "2024-12-02T23:51:28Z")

</div>

The core manages database migrations for its own tables. Are you referring to custom packages and such? Or content differences between a stage and production?

There are CLI tools available to assist with creating migrations:

```plaintext
$ ./vendor/bin/concrete help migrate
Description:
  Execute a migration to a specified version or the latest available version.

Usage:
  migrations:migrate [options] [--] [<version>]
  migrate

Arguments:
  version The version number (YYYYMMDDHHMMSS) or alias (first, prev, next, latest) to migrate to. [default: "latest"]

Options:
      --write-sql[=WRITE-SQL] The path to output the migration SQL file instead of executing it. Defaults to current working directory. [default: false]
      --dry-run Execute the migration as a dry run.
      --query-time Time all the queries individually.
      --allow-no-migration Do not throw an exception if no migration is available.
      --all-or-nothing[=ALL-OR-NOTHING] Wrap the entire migration in a transaction. [default: false]
      --configuration[=CONFIGURATION] The path to a migrations configuration file.
      --db-configuration[=DB-CONFIGURATION] The path to a database connection configuration file.
  -h, --help Display help for the given command. When no command is given display help for the list command
  -q, --quiet Do not output any message
  -V, --version Display this application version
      --ansi|--no-ansi Force (or disable --no-ansi) ANSI output
  -n, --no-interaction Do not ask any interactive question
  -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Help:
  The migrations:migrate command executes a migration to a specified version or the latest available version:
  
      ./vendor/bin/concrete migrations:migrate
  
  You can optionally manually specify the version you wish to migrate to:
  
      ./vendor/bin/concrete migrations:migrate YYYYMMDDHHMMSS
  
  You can specify the version you wish to migrate to using an alias:
  
      ./vendor/bin/concrete migrations:migrate prev
      These alias are defined : first, latest, prev, current and next
  
  You can specify the version you wish to migrate to using an number against the current version:
  
      ./vendor/bin/concrete migrations:migrate current+3
  
  You can also execute the migration as a --dry-run:
  
      ./vendor/bin/concrete migrations:migrate YYYYMMDDHHMMSS --dry-run
  
  You can output the would be executed SQL statements to a file with --write-sql:
  
      ./vendor/bin/concrete migrations:migrate YYYYMMDDHHMMSS --write-sql
  
  Or you can also execute the migration without a warning message which you need to interact with:
  
      ./vendor/bin/concrete migrations:migrate --no-interaction
  
  You can also time all the different queries if you wanna know which one is taking so long:
  
      ./vendor/bin/concrete migrations:migrate --query-time
  
  Use the --all-or-nothing option to wrap the entire migration in a transaction.

```
