index.rst 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. DoctrineMigrationsBundle
  2. ========================
  3. Database migrations are a way to safely update your database schema both locally
  4. and on production. Instead of running the ``doctrine:schema:update`` command or
  5. applying the database changes manually with SQL statements, migrations allow to
  6. replicate the changes in your database schema in a safe manner.
  7. Migrations are available in Symfony applications via the `DoctrineMigrationsBundle`_,
  8. which uses the external `Doctrine Database Migrations`_ library. Read the
  9. `documentation`_ of that library if you need a general introduction about migrations.
  10. Installation
  11. ------------
  12. Run this command in your terminal:
  13. .. code-block:: terminal
  14. $ composer require doctrine/doctrine-migrations-bundle "^3.0"
  15. If you don't use `Symfony Flex`_, you must enable the bundle manually in the application:
  16. .. code-block:: php
  17. // config/bundles.php
  18. // in older Symfony apps, enable the bundle in app/AppKernel.php
  19. return [
  20. // ...
  21. Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
  22. ];
  23. Configuration
  24. -------------
  25. If you use Symfony Flex, the ``doctrine_migrations.yaml`` config file is created
  26. automatically. Otherwise, create the following file and configure it for your
  27. application:
  28. .. code-block:: yaml
  29. # config/packages/doctrine_migrations.yaml
  30. doctrine_migrations:
  31. # List of namespace/path pairs to search for migrations, at least one required
  32. migrations_paths:
  33. 'App\Migrations': '%kernel.project_dir%/src/App'
  34. 'AnotherApp\Migrations': '/path/to/other/migrations'
  35. 'SomeBundle\Migrations': '@SomeBundle/Migrations'
  36. # List of additional migration classes to be loaded, optional
  37. migrations:
  38. - 'App\Migrations\Version123'
  39. - 'App\Migrations\Version123'
  40. # Connection to use for the migrations
  41. connection: default
  42. # Entity manager to use for migrations. This overrides the "connection" setting.
  43. em: default
  44. storage:
  45. # Default (SQL table) metadata storage configuration
  46. table_storage:
  47. table_name: 'doctrine_migration_versions'
  48. version_column_name: 'version'
  49. version_column_length: 1024
  50. executed_at_column_name: 'executed_at'
  51. # Possible values: "BY_YEAR", "BY_YEAR_AND_MONTH", false
  52. organize_migrations: false
  53. # Path to your custom migrations template
  54. custom_template: ~
  55. # Run all migrations in a transaction.
  56. all_or_nothing: false
  57. # Adds an extra check in the generated migrations to ensure that is executed on the same database type.
  58. check_database_platform: true
  59. services:
  60. # Custom migration sorting service id
  61. 'Doctrine\Migrations\Version\Comparator': ~
  62. # Custom migration classes factory
  63. 'Doctrine\Migrations\Version\MigrationFactory': ~
  64. factories:
  65. # Custom migration sorting service id via callables (MyCallableFactory must be a callable)
  66. 'Doctrine\Migrations\Version\Comparator': 'MyCallableFactory'
  67. - The ``services`` node allows you to provide custom services to the underlying ``DependencyFactory`` part of ``doctrine/migrations``.
  68. - The node ``factories`` is similar to ``services``, with the difference that it accepts only callables.
  69. The provided callable must return the service to be passed to the ``DependencyFactory``.
  70. The callable will receive as first argument the ``DependencyFactory`` itself,
  71. allowing you to fetch other dependencies from the factory while instantiating your custom dependencies.
  72. Usage
  73. -----
  74. All of the migrations functionality is contained in a few console commands:
  75. .. code-block:: terminal
  76. doctrine
  77. doctrine:migrations:current [current] Outputs the current version.
  78. doctrine:migrations:diff [diff] Generate a migration by comparing your current database to your mapping information.
  79. doctrine:migrations:dump-schema [dump-schema] Dump the schema for your database to a migration.
  80. doctrine:migrations:execute [execute] Execute a single migration version up or down manually.
  81. doctrine:migrations:generate [generate] Generate a blank migration class.
  82. doctrine:migrations:latest [latest] Outputs the latest version number
  83. doctrine:migrations:migrate [migrate] Execute a migration to a specified version or the latest available version.
  84. doctrine:migrations:rollup [rollup] Roll migrations up by deleting all tracked versions and inserting the one version that exists.
  85. doctrine:migrations:status [status] View the status of a set of migrations.
  86. doctrine:migrations:up-to-date [up-to-date] Tells you if your schema is up-to-date.
  87. doctrine:migrations:version [version] Manually add and delete migration versions from the version table.
  88. doctrine:migrations:sync-metadata-storage [sync-metadata-storage] Ensures that the metadata storage is at the latest version.
  89. doctrine:migrations:list [list-migrations] Display a list of all available migrations and their status.
  90. Start by getting the status of migrations in your application by running
  91. the ``status`` command:
  92. .. code-block:: terminal
  93. $ php bin/console doctrine:migrations:status
  94. This command will show you generic information about the migration status, such as how many migrations have been
  95. already executed, which still need to run, and the database in use.
  96. Now, you can start working with migrations by generating a new blank migration
  97. class. Later, you'll learn how Doctrine can generate migrations automatically
  98. for you.
  99. .. code-block:: terminal
  100. $ php bin/console doctrine:migrations:generate
  101. Have a look at the newly generated migration class and you will see something
  102. like the following:
  103. .. code-block:: php
  104. declare(strict_types=1);
  105. namespace DoctrineMigrations;
  106. use Doctrine\DBAL\Schema\Schema;
  107. use Doctrine\Migrations\AbstractMigration;
  108. /**
  109. * Auto-generated Migration: Please modify to your needs!
  110. */
  111. final class Version20180605025653 extends AbstractMigration
  112. {
  113. public function getDescription() : string
  114. {
  115. return '';
  116. }
  117. public function up(Schema $schema) : void
  118. {
  119. // this up() migration is auto-generated, please modify it to your needs
  120. }
  121. public function down(Schema $schema) : void
  122. {
  123. // this down() migration is auto-generated, please modify it to your needs
  124. }
  125. }
  126. If you run the ``status`` command again it will now show that you have one new
  127. migration to execute:
  128. .. code-block:: terminal
  129. $ php bin/console doctrine:migrations:status --show-versions
  130. Now you can add some migration code to the ``up()`` and ``down()`` methods and
  131. finally migrate when you're ready:
  132. .. code-block:: terminal
  133. $ php bin/console doctrine:migrations:migrate 'DoctrineMigrations\Version20180605025653'
  134. For more information on how to write the migrations themselves (i.e. how to
  135. fill in the ``up()`` and ``down()`` methods), see the official Doctrine Migrations
  136. `documentation`_.
  137. Running Migrations during Deployment
  138. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  139. Of course, the end goal of writing migrations is to be able to use them to
  140. reliably update your database structure when you deploy your application.
  141. By running the migrations locally (or on a beta server), you can ensure that
  142. the migrations work as you expect.
  143. When you do finally deploy your application, you just need to remember to run
  144. the ``doctrine:migrations:migrate`` command. Internally, Doctrine creates
  145. a ``migration_versions`` table inside your database and tracks which migrations
  146. have been executed there. So, no matter how many migrations you've created
  147. and executed locally, when you run the command during deployment, Doctrine
  148. will know exactly which migrations it hasn't run yet by looking at the ``migration_versions``
  149. table of your production database. Regardless of what server you're on, you
  150. can always safely run this command to execute only the migrations that haven't
  151. been run yet on *that* particular database.
  152. Skipping Migrations
  153. ~~~~~~~~~~~~~~~~~~~
  154. You can skip single migrations by explicitly adding them to the ``migration_versions`` table:
  155. .. code-block:: terminal
  156. $ php bin/console doctrine:migrations:version 'App\Migrations\Version123' --add
  157. .. tip::
  158. Pay attention to the single quotes (``'``) used in the command above, without them
  159. or with the double quotes (``"``) the command will not work properly.
  160. Doctrine will then assume that this migration has already been run and will ignore it.
  161. Migration Dependencies
  162. ----------------------
  163. Migrations can have dependencies on external services (such as geolocation, mailer, data processing services...) that
  164. can be used to have more powerful migrations. Those dependencies are not automatically injected into your migrations
  165. but need to be injected using custom migrations factories.
  166. Here is an example on how to inject the service container into your migrations:
  167. .. configuration-block::
  168. .. code-block:: yaml
  169. # config/packages/doctrine_migrations.yaml
  170. doctrine_migrations:
  171. services:
  172. 'Doctrine\Migrations\Version\MigrationFactory': 'App\Migrations\Factory\MigrationFactoryDecorator'
  173. # config/services.yaml
  174. services:
  175. Doctrine\Migrations\Version\DbalMigrationFactory: ~
  176. App\Migrations\Factory\MigrationFactoryDecorator:
  177. decorates: Doctrine\Migrations\Version\DbalMigrationFactory
  178. arguments: ['@App\Migrations\Factory\MigrationFactoryDecorator.inner', '@service_container']
  179. .. code-block:: php
  180. declare(strict_types=1);
  181. namespace App\Migrations\Factory;
  182. use Doctrine\Migrations\AbstractMigration;
  183. use Doctrine\Migrations\Version\MigrationFactory;
  184. use Symfony\Component\DependencyInjection\ContainerAwareInterface;
  185. use Symfony\Component\DependencyInjection\ContainerInterface;
  186. class MigrationFactoryDecorator implements MigrationFactory
  187. {
  188. private $migrationFactory;
  189. private $container;
  190. public function __construct(MigrationFactory $migrationFactory, ContainerInterface $container)
  191. {
  192. $this->migrationFactory = $migrationFactory;
  193. $this->container = $container;
  194. }
  195. public function createVersion(string $migrationClassName): AbstractMigration
  196. {
  197. $instance = $this->migrationFactory->createVersion($migrationClassName);
  198. if ($instance instanceof ContainerAwareInterface) {
  199. $instance->setContainer($this->container);
  200. }
  201. return $instance;
  202. }
  203. }
  204. .. tip::
  205. If your migration class implements the interface ``Symfony\Component\DependencyInjection\ContainerAwareInterface``
  206. this bundle will automatically inject the default symfony container into your migration class
  207. (this because the ``MigrationFactoryDecorator`` shown in this example is the default migration factory used by this bundle).
  208. Generating Migrations Automatically
  209. -----------------------------------
  210. In reality, you should rarely need to write migrations manually, as the migrations
  211. library can generate migration classes automatically by comparing your Doctrine
  212. mapping information (i.e. what your database *should* look like) with your
  213. actual current database structure.
  214. For example, suppose you create a new ``User`` entity and add mapping information
  215. for Doctrine's ORM:
  216. .. configuration-block::
  217. .. code-block:: php-annotations
  218. // src/Entity/User.php
  219. namespace App\Entity;
  220. use Doctrine\ORM\Mapping as ORM;
  221. /**
  222. * @ORM\Entity
  223. * @ORM\Table(name="hello_user")
  224. */
  225. class User
  226. {
  227. /**
  228. * @ORM\Id
  229. * @ORM\Column(type="integer")
  230. * @ORM\GeneratedValue(strategy="AUTO")
  231. */
  232. private $id;
  233. /**
  234. * @ORM\Column(type="string", length=255)
  235. */
  236. private $name;
  237. .. code-block:: yaml
  238. # config/doctrine/User.orm.yaml
  239. App\Entity\User:
  240. type: entity
  241. table: user
  242. id:
  243. id:
  244. type: integer
  245. generator:
  246. strategy: AUTO
  247. fields:
  248. name:
  249. type: string
  250. length: 255
  251. .. code-block:: xml
  252. <!-- config/doctrine/User.orm.xml -->
  253. <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
  254. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  255. xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
  256. http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
  257. <entity name="App\Entity\User" table="user">
  258. <id name="id" type="integer" column="id">
  259. <generator strategy="AUTO"/>
  260. </id>
  261. <field name="name" column="name" type="string" length="255" />
  262. </entity>
  263. </doctrine-mapping>
  264. With this information, Doctrine is now ready to help you persist your new
  265. ``User`` object to and from the ``user`` table. Of course, this table
  266. doesn't exist yet! Generate a new migration for this table automatically by
  267. running the following command:
  268. .. code-block:: terminal
  269. $ php bin/console doctrine:migrations:diff
  270. You should see a message that a new migration class was generated based on
  271. the schema differences. If you open this file, you'll find that it has the
  272. SQL code needed to create the ``user`` table. Next, run the migration
  273. to add the table to your database:
  274. .. code-block:: terminal
  275. $ php bin/console doctrine:migrations:migrate
  276. The moral of the story is this: after each change you make to your Doctrine
  277. mapping information, run the ``doctrine:migrations:diff`` command to automatically
  278. generate your migration classes.
  279. If you do this from the very beginning of your project (i.e. so that even
  280. the first tables were loaded via a migration class), you'll always be able
  281. to create a fresh database and run your migrations in order to get your database
  282. schema fully up to date. In fact, this is an easy and dependable workflow
  283. for your project.
  284. If you don't want to use this workflow and instead create your schema via
  285. ``doctrine:schema:create``, you can tell Doctrine to skip all existing migrations:
  286. .. code-block:: terminal
  287. $ php bin/console doctrine:migrations:version --add --all
  288. Otherwise Doctrine will try to run all migrations, which probably will not work.
  289. Manual Tables
  290. -------------
  291. It is a common use case, that in addition to your generated database structure
  292. based on your doctrine entities you might need custom tables. By default such
  293. tables will be removed by the ``doctrine:migrations:diff`` command.
  294. If you follow a specific scheme you can configure doctrine/dbal to ignore those
  295. tables. Let's say all custom tables will be prefixed by ``t_``. In this case you
  296. just have to add the following configuration option to your doctrine configuration:
  297. .. configuration-block::
  298. .. code-block:: yaml
  299. doctrine:
  300. dbal:
  301. schema_filter: ~^(?!t_)~
  302. .. code-block:: xml
  303. <doctrine:dbal schema-filter="~^(?!t_)~" />
  304. .. code-block:: php
  305. $container->loadFromExtension('doctrine', array(
  306. 'dbal' => array(
  307. 'schema_filter' => '~^(?!t_)~',
  308. // ...
  309. ),
  310. // ...
  311. ));
  312. This ignores the tables, and any named objects such as sequences, on the DBAL level and they will be ignored by the diff command.
  313. Note that if you have multiple connections configured then the ``schema_filter`` configuration
  314. will need to be placed per-connection.
  315. .. _documentation: https://www.doctrine-project.org/projects/doctrine-migrations/en/current/index.html
  316. .. _DoctrineMigrationsBundle: https://github.com/doctrine/DoctrineMigrationsBundle
  317. .. _`Doctrine Database Migrations`: https://github.com/doctrine/migrations
  318. .. _`Symfony Flex`: https://symfony.com/doc/current/setup/flex.html