mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-06 14:19:23 +08:00
1071 lines
39 KiB
Markdown
1071 lines
39 KiB
Markdown
Migracje bazy danych
|
||
====================
|
||
|
||
W czasie rozwoju i utrzymywania aplikacji zasilanej danymi z bazy danych, struktura tej ostatniej ewoluuje podobnie jak
|
||
sam kod źródłowy. Przykładowo, rozbudowując aplikację konieczne jest dodanie nowej tabeli, lub też już po wydaniu aplikacji
|
||
na serwerze produkcyjnym przydałby się indeks, aby poprawić wydajność zapytania itd. Zmiana struktury bazy danych często
|
||
pociąga za sobą zmiany w kodzie źródłowym, dlatego też Yii udostępnia funkcjonalność tak zwanych *migracji bazodanowych*,
|
||
która pozwala na kontrolowanie zmian w bazie danych (*migracji*).
|
||
|
||
Poniższe kroki pokazują, jak migracje mogą być wykorzystane przez zespół deweloperski w czasie pracy:
|
||
|
||
1. Tomek tworzy nową migrację (np. dodaje nową tabelę, zmienia definicję kolumny, itp.).
|
||
2. Tomek rejestruje ("commit") nową migrację w systemie kontroli wersji (np. Git, Mercurial).
|
||
3. Mariusz uaktualnia swoje repozytorium z systemu kontroli wersji i otrzymuje nową migrację.
|
||
4. Mariusz dodaje migrację do swojej lokalnej bazy danych, dzięki czemu synchronizuje ją ze zmianami, które wprowadził
|
||
Tomek.
|
||
|
||
A poniższe kroki opisują w skrócie jak stworzyć nowe wydanie z migracją bazy danych na produkcji:
|
||
|
||
1. Rafał tworzy tag wydania dla repozytorium projektu, który zawiera nowe migracje bazy danych.
|
||
2. Rafał uaktualnia kod źródłowy na serwerze produkcyjnym do otagowanej wersji.
|
||
3. Rafał dodaje zebrane nowe migracje do produkcyjnej bazy danych.
|
||
|
||
Yii udostępnia zestaw narzędzi konsolowych, które pozwalają na:
|
||
|
||
* utworzenie nowych migracji;
|
||
* dodanie migracji;
|
||
* cofnięcie migracji;
|
||
* ponowne zaaplikowanie migracji;
|
||
* wyświetlenie historii migracji i jej statusu.
|
||
|
||
Powyższe narzędzia są dostępne poprzez komendę `yii migrate`. W tej sekcji opiszemy szczegółowo w jaki sposób z nich
|
||
korzystać. Możesz również zapoznać się ze sposobem użycia narzędzi w konsoli za pomocą komendy pomocy `yii help migrate`.
|
||
|
||
> Tip: Migracje mogą modyfikować nie tylko schemat bazy danych, ale również same dane, a także mogą służyć do innych zadań
|
||
jak tworzenie hierarchi kontroli dostępu dla ról (RBAC) lub czyszczenie pamięci podręcznej.
|
||
|
||
> Note: Modyfikowanie danych w migracji zwykle jest znacznie prostsze, jeśli użyje się do tego klas
|
||
[Active Record](db-active-record.md), dzięki logice już tam zaimplementowanej. Należy jednak pamiętać, że logika
|
||
aplikacji jest podatna na częste zmiany, a naturalnym stanem kodu migracji jest jego stałość - w przypadku zmian w
|
||
warstwie Active Record aplikacji ryzykujemy zepsucie migracji, które z niej korzystają. Z tego powodu kod migracji
|
||
powinien być utrzymywany niezależnie od pozostałej logiki aplikacji.
|
||
|
||
|
||
## Tworzenie migracji <span id="creating-migrations"></span>
|
||
|
||
Aby utworzyć nową migrację, uruchom poniższą komendę:
|
||
|
||
```
|
||
yii migrate/create <nazwa>
|
||
```
|
||
|
||
Wymagany argument `nazwa` przekazuje zwięzły opis migracji. Przykładowo, jeśli migracja ma dotyczyć utworzenia nowej
|
||
tabeli o nazwie *news*, możesz użyć jako argumentu `create_news_table` i uruchomić komendę:
|
||
|
||
```
|
||
yii migrate/create create_news_table
|
||
```
|
||
|
||
> Note: Argument `nazwa` zostanie użyty jako część nazwy klasy nowej migracji i z tego powodu powinien składać się tylko
|
||
z łacińskich liter, cyfr i/lub znaków podkreślenia.
|
||
|
||
Powyższa komenda utworzy nowy plik klasy PHP o nazwie podobnej do `m150101_185401_create_news_table.php` w folderze
|
||
`@app/migrations`. Plik będzie zawierał poniższy kod, gdzie zadeklarowany jest szkielet klasy `m150101_185401_create_news_table`:
|
||
|
||
```php
|
||
<?php
|
||
|
||
use yii\db\Migration;
|
||
|
||
class m150101_185401_create_news_table extends Migration
|
||
{
|
||
public function up()
|
||
{
|
||
|
||
}
|
||
|
||
public function down()
|
||
{
|
||
echo "m101129_185401_create_news_table cannot be reverted.\n";
|
||
|
||
return false;
|
||
}
|
||
|
||
/*
|
||
// Use safeUp/safeDown to run migration code within a transaction
|
||
public function safeUp()
|
||
{
|
||
}
|
||
|
||
public function safeDown()
|
||
{
|
||
}
|
||
*/
|
||
}
|
||
```
|
||
|
||
Każda migracja zdefiniowana jest jako klasa PHP rozszerzająca [[yii\db\Migration]]. Nazwa klasy migracji jest generowana
|
||
automatycznie w formacie `m<YYMMDD_HHMMSS>_<Nazwa>`, gdzie
|
||
|
||
* `<YYMMDD_HHMMSS>` to data i czas UTC wskazujące na moment utworzenia migracji,
|
||
* `<Nazwa>` jest identyczna z wartością argumentu `nazwa` podanego dla komendy.
|
||
|
||
Wewnątrz klasy migracji należy napisać kod w metodzie `up()`, która wprowadzi zmiany w strukturze bazy danych.
|
||
Można również napisać kod w metodzie `down()`, który spowoduje cofnięcie zmian wprowadzonych w `up()`. Metoda `up()` jest
|
||
uruchamiana w momencie aktualizacji bazy, a `down()` w momencie przywracania jej do poprzedniego stanu.
|
||
Poniższy kod pokazuje, jak można zaimplementować klasę migracji, aby utworzyć tabelę `news`:
|
||
|
||
```php
|
||
<?php
|
||
|
||
use yii\db\Schema;
|
||
use yii\db\Migration;
|
||
|
||
class m150101_185401_create_news_table extends Migration
|
||
{
|
||
public function up()
|
||
{
|
||
$this->createTable('news', [
|
||
'id' => Schema::TYPE_PK,
|
||
'title' => Schema::TYPE_STRING . ' NOT NULL',
|
||
'content' => Schema::TYPE_TEXT,
|
||
]);
|
||
}
|
||
|
||
public function down()
|
||
{
|
||
$this->dropTable('news');
|
||
}
|
||
}
|
||
```
|
||
|
||
> Info: Nie wszystkie migracje są odwracalne. Dla przykładu, jeśli w `up()` usuwane są wiersze z tabeli, możesz nie być
|
||
w stanie przywrócić ich w metodzie `down()`. Może też zdarzyć się, że celowo nie podasz nic w `down()` - cofanie zmian
|
||
migracji bazy danych nie jest czymś powszechnym - w takim wypadku należy zwrócić `false` w metodzie `down()`, aby
|
||
wyraźnie wskazać, że migracja nie jest odwracalna.
|
||
|
||
Podstawowa klasa migracji [[yii\db\Migration]] umożliwia połączenie z bazą danych poprzez właściwość
|
||
[[yii\db\Migration::db|db]]. Możesz użyć jej do modyfikowania schematu bazy za pomocą metod opisanych w sekcji
|
||
[Praca ze schematem bazy danych](db-dao.md#database-schema).
|
||
|
||
Przy tworzeniu tabeli albo kolumny zamiast używać rzeczywistych typów, powinno się stosować *typy abstrakcyjne*, dzięki
|
||
czemu migracje będą niezależne od pojedynczych silników bazodanowych. Klasa [[yii\db\Schema]] definiuje zestaw stałych,
|
||
które reprezentują wspierane typy abstrakcyjne. Stałe te nazwane są według schematu `TYPE_<Nazwa>`. Dla przykładu,
|
||
`TYPE_PK` odnosi się do typu klucza głównego z autoinkrementacją; `TYPE_STRING` do typu łańcucha znaków. Kiedy migracja
|
||
jest dodawana do konkretnej bazy danych, typy abstrakcyjne są tłumaczone na odpowiadające im typy rzeczywiste. W przypadku
|
||
MySQL, `TYPE_PK` jest zamieniony w `int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY`, a `TYPE_STRING` staje się `varchar(255)`.
|
||
|
||
Możesz łączyć abstrakcyjne typy z dodatkowymi definicjami - w powyższym przykładzie ` NOT NULL` jest dodane do
|
||
`Schema::TYPE_STRING`, aby oznaczyć, że kolumna nie może być ustawiona jako `null`.
|
||
|
||
> Info: Mapowanie typów abstrakcyjnych na rzeczywiste jest określone we właściwości [[yii\db\QueryBuilder::$typeMap|$typeMap]]
|
||
dla każdej klasy `QueryBuilder` poszczególnych wspieranych silników baz danych.
|
||
|
||
Począwszy od wersji 2.0.6, możesz skorzystać z nowej klasy budowania schematów, która pozwala na znacznie wygodniejszy
|
||
sposób definiowana kolumn. Dzięki temu migracja z przykładu powyżej może być napisana następująco:
|
||
|
||
```php
|
||
<?php
|
||
|
||
use yii\db\Migration;
|
||
|
||
class m150101_185401_create_news_table extends Migration
|
||
{
|
||
public function up()
|
||
{
|
||
$this->createTable('news', [
|
||
'id' => $this->primaryKey(),
|
||
'title' => $this->string()->notNull(),
|
||
'content' => $this->text(),
|
||
]);
|
||
}
|
||
|
||
public function down()
|
||
{
|
||
$this->dropTable('news');
|
||
}
|
||
}
|
||
```
|
||
|
||
Lista wszystkich metod do definiowania typów kolumn dostępna jest w dokumentacji API dla [[yii\db\SchemaBuilderTrait]].
|
||
|
||
|
||
## Generowanie migracji <span id="generating-migrations"></span>
|
||
|
||
Począwszy od wersji 2.0.7 konsola migracji pozwala na wygodne utworzenie nowej migracji.
|
||
|
||
Jeśli nazwa migracji podana jest w jednej z rozpoznawalnych form, np. `create_xxx_table` lub `drop_xxx_table`, wtedy
|
||
wygenerowany plik migracji będzie zawierał dodatkowy kod, w tym przypadku odpowiednio kod tworzenia i usuwania tabeli.
|
||
Poniżej opisane są wszystkie warianty tej funkcjonalności.
|
||
|
||
### Tworzenie tabeli
|
||
|
||
```
|
||
yii migrate/create create_post_table
|
||
```
|
||
|
||
generuje
|
||
|
||
```php
|
||
/**
|
||
* Handles the creation for table `post`.
|
||
*/
|
||
class m150811_220037_create_post_table extends Migration
|
||
{
|
||
/**
|
||
* {@inheritdoc}
|
||
*/
|
||
public function up()
|
||
{
|
||
$this->createTable('post', [
|
||
'id' => $this->primaryKey()
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* {@inheritdoc}
|
||
*/
|
||
public function down()
|
||
{
|
||
$this->dropTable('post');
|
||
}
|
||
}
|
||
```
|
||
|
||
Aby jednocześnie od razu dodać kolumny tabeli, zdefiniuj je za pomocą opcji `--fields`.
|
||
|
||
```
|
||
yii migrate/create create_post_table --fields="title:string,body:text"
|
||
```
|
||
|
||
generuje
|
||
|
||
```php
|
||
/**
|
||
* Handles the creation for table `post`.
|
||
*/
|
||
class m150811_220037_create_post_table extends Migration
|
||
{
|
||
/**
|
||
* {@inheritdoc}
|
||
*/
|
||
public function up()
|
||
{
|
||
$this->createTable('post', [
|
||
'id' => $this->primaryKey(),
|
||
'title' => $this->string(),
|
||
'body' => $this->text(),
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* {@inheritdoc}
|
||
*/
|
||
public function down()
|
||
{
|
||
$this->dropTable('post');
|
||
}
|
||
}
|
||
|
||
```
|
||
|
||
Możesz określić też więcej parametrów kolumny.
|
||
|
||
```
|
||
yii migrate/create create_post_table --fields="title:string(12):notNull:unique,body:text"
|
||
```
|
||
|
||
generuje
|
||
|
||
```php
|
||
/**
|
||
* Handles the creation for table `post`.
|
||
*/
|
||
class m150811_220037_create_post_table extends Migration
|
||
{
|
||
/**
|
||
* {@inheritdoc}
|
||
*/
|
||
public function up()
|
||
{
|
||
$this->createTable('post', [
|
||
'id' => $this->primaryKey(),
|
||
'title' => $this->string(12)->notNull()->unique(),
|
||
'body' => $this->text()
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* {@inheritdoc}
|
||
*/
|
||
public function down()
|
||
{
|
||
$this->dropTable('post');
|
||
}
|
||
}
|
||
```
|
||
|
||
> Note: Klucz główny jest dodawany automatycznie i nazwany domyślnie `id`. Jeśli chcesz użyć innej nazwy, możesz
|
||
zdefiniować go bezpośrednio np. `--fields="name:primaryKey"`.
|
||
|
||
#### Klucze obce
|
||
|
||
Począwszy od wersji 2.0.8 generator pozwala na zdefiniowanie kluczy obcych za pomocą opcji `foreignKey`.
|
||
|
||
```
|
||
yii migrate/create create_post_table --fields="author_id:integer:notNull:foreignKey(user),category_id:integer:defaultValue(1):foreignKey,title:string,body:text"
|
||
```
|
||
|
||
generuje
|
||
|
||
```php
|
||
/**
|
||
* Handles the creation for table `post`.
|
||
* Has foreign keys to the tables:
|
||
*
|
||
* - `user`
|
||
* - `category`
|
||
*/
|
||
class m160328_040430_create_post_table extends Migration
|
||
{
|
||
/**
|
||
* {@inheritdoc}
|
||
*/
|
||
public function up()
|
||
{
|
||
$this->createTable('post', [
|
||
'id' => $this->primaryKey(),
|
||
'author_id' => $this->integer()->notNull(),
|
||
'category_id' => $this->integer()->defaultValue(1),
|
||
'title' => $this->string(),
|
||
'body' => $this->text(),
|
||
]);
|
||
|
||
// creates index for column `author_id`
|
||
$this->createIndex(
|
||
'idx-post-author_id',
|
||
'post',
|
||
'author_id'
|
||
);
|
||
|
||
// add foreign key for table `user`
|
||
$this->addForeignKey(
|
||
'fk-post-author_id',
|
||
'post',
|
||
'author_id',
|
||
'user',
|
||
'id',
|
||
'CASCADE'
|
||
);
|
||
|
||
// creates index for column `category_id`
|
||
$this->createIndex(
|
||
'idx-post-category_id',
|
||
'post',
|
||
'category_id'
|
||
);
|
||
|
||
// add foreign key for table `category`
|
||
$this->addForeignKey(
|
||
'fk-post-category_id',
|
||
'post',
|
||
'category_id',
|
||
'category',
|
||
'id',
|
||
'CASCADE'
|
||
);
|
||
}
|
||
|
||
/**
|
||
* {@inheritdoc}
|
||
*/
|
||
public function down()
|
||
{
|
||
// drops foreign key for table `user`
|
||
$this->dropForeignKey(
|
||
'fk-post-author_id',
|
||
'post'
|
||
);
|
||
|
||
// drops index for column `author_id`
|
||
$this->dropIndex(
|
||
'idx-post-author_id',
|
||
'post'
|
||
);
|
||
|
||
// drops foreign key for table `category`
|
||
$this->dropForeignKey(
|
||
'fk-post-category_id',
|
||
'post'
|
||
);
|
||
|
||
// drops index for column `category_id`
|
||
$this->dropIndex(
|
||
'idx-post-category_id',
|
||
'post'
|
||
);
|
||
|
||
$this->dropTable('post');
|
||
}
|
||
}
|
||
```
|
||
|
||
Umiejscowienie słowa `foreignKey` w definicji kolumny nie ma znaczenia dla generatora, zatem:
|
||
|
||
- `author_id:integer:notNull:foreignKey(user)`
|
||
- `author_id:integer:foreignKey(user):notNull`
|
||
- `author_id:foreignKey(user):integer:notNull`
|
||
|
||
wygenerują ten sam kod.
|
||
|
||
Opcja `foreignKey` może być wzbogacona o parametr w nawiasach, który oznacza nazwę tabeli relacji dla generowanego
|
||
klucza obcego. Bez tego parametru użyta zostanie nazwa tabeli relacji zgodna z nazwą kolumny.
|
||
|
||
W przykładzie powyżej `author_id:integer:notNull:foreignKey(user)` wygeneruje kolumnę o nazwie `author_id` z kluczem
|
||
obcym wskazującym na tabelę `user`, natomiast `category_id:integer:defaultValue(1):foreignKey` wygeneruje kolumnę
|
||
`category_id` z kluczem obcym wskazującym na tabelę `category`.
|
||
|
||
Począwszy od wersji 2.0.11, dla `foreignKey` można podać drugi parametr, oddzielony białym znakiem, z nazwą kolumny
|
||
relacji dla generowanego klucza obcego. Jeśli drugi parametr nie jest podany, nazwa kolumny jest pobierana ze schematu tabeli.
|
||
Jeśli schemat nie istnieje , klucz główny nie jest ustawiony lub jest kluczem kompozytowym, używana jest domyślna nazwa `id`.
|
||
|
||
### Usuwanie tabeli
|
||
|
||
```
|
||
yii migrate/create drop_post_table --fields="title:string(12):notNull:unique,body:text"
|
||
```
|
||
|
||
generuje
|
||
|
||
```php
|
||
class m150811_220037_drop_post_table extends Migration
|
||
{
|
||
public function up()
|
||
{
|
||
$this->dropTable('post');
|
||
}
|
||
|
||
public function down()
|
||
{
|
||
$this->createTable('post', [
|
||
'id' => $this->primaryKey(),
|
||
'title' => $this->string(12)->notNull()->unique(),
|
||
'body' => $this->text()
|
||
]);
|
||
}
|
||
}
|
||
```
|
||
|
||
### Dodawanie kolumny
|
||
|
||
Jeśli nazwa migracji jest w postaci `add_xxx_column_to_yyy_table`, wtedy plik będzie zawierał wywołania metod `addColumn`
|
||
i `dropColumn`.
|
||
|
||
Aby dodać kolumnę:
|
||
|
||
```
|
||
yii migrate/create add_position_column_to_post_table --fields="position:integer"
|
||
```
|
||
|
||
co generuje
|
||
|
||
```php
|
||
class m150811_220037_add_position_column_to_post_table extends Migration
|
||
{
|
||
public function up()
|
||
{
|
||
$this->addColumn('post', 'position', $this->integer());
|
||
}
|
||
|
||
public function down()
|
||
{
|
||
$this->dropColumn('post', 'position');
|
||
}
|
||
}
|
||
```
|
||
|
||
Możesz dodać wiele kolumn jednocześnie:
|
||
|
||
```
|
||
yii migrate/create add_xxx_column_yyy_column_to_zzz_table --fields="xxx:integer,yyy:text"
|
||
```
|
||
|
||
### Usuwanie kolumny
|
||
|
||
Jeśli nazwa migracji jest w postaci `drop_xxx_column_from_yyy_table`, wtedy plik będzie zawierał wywołania metod
|
||
`dropColumn` i `addColumn`.
|
||
|
||
```php
|
||
yii migrate/create drop_position_column_from_post_table --fields="position:integer"
|
||
```
|
||
|
||
generuje
|
||
|
||
```php
|
||
class m150811_220037_drop_position_column_from_post_table extends Migration
|
||
{
|
||
public function up()
|
||
{
|
||
$this->dropColumn('post', 'position');
|
||
}
|
||
|
||
public function down()
|
||
{
|
||
$this->addColumn('post', 'position', $this->integer());
|
||
}
|
||
}
|
||
```
|
||
|
||
### Dodawanie tabeli węzła
|
||
|
||
Jeśli nazwa migracji jest w postaci `create_junction_table_for_xxx_and_yyy_tables` lub `create_junction_xxx_and_yyy_tables`,
|
||
wtedy plik będzie zawierał kod potrzebny do wygenerowania tabeli węzła pomiędzy tabelami `xxx` i `yyy`.
|
||
|
||
```
|
||
yii migrate/create create_junction_table_for_post_and_tag_tables --fields="created_at:dateTime"
|
||
```
|
||
|
||
generuje
|
||
|
||
```php
|
||
/**
|
||
* Handles the creation for table `post_tag`.
|
||
* Has foreign keys to the tables:
|
||
*
|
||
* - `post`
|
||
* - `tag`
|
||
*/
|
||
class m160328_041642_create_junction_table_for_post_and_tag_tables extends Migration
|
||
{
|
||
/**
|
||
* {@inheritdoc}
|
||
*/
|
||
public function up()
|
||
{
|
||
$this->createTable('post_tag', [
|
||
'post_id' => $this->integer(),
|
||
'tag_id' => $this->integer(),
|
||
'created_at' => $this->dateTime(),
|
||
'PRIMARY KEY(post_id, tag_id)',
|
||
]);
|
||
|
||
// creates index for column `post_id`
|
||
$this->createIndex(
|
||
'idx-post_tag-post_id',
|
||
'post_tag',
|
||
'post_id'
|
||
);
|
||
|
||
// add foreign key for table `post`
|
||
$this->addForeignKey(
|
||
'fk-post_tag-post_id',
|
||
'post_tag',
|
||
'post_id',
|
||
'post',
|
||
'id',
|
||
'CASCADE'
|
||
);
|
||
|
||
// creates index for column `tag_id`
|
||
$this->createIndex(
|
||
'idx-post_tag-tag_id',
|
||
'post_tag',
|
||
'tag_id'
|
||
);
|
||
|
||
// add foreign key for table `tag`
|
||
$this->addForeignKey(
|
||
'fk-post_tag-tag_id',
|
||
'post_tag',
|
||
'tag_id',
|
||
'tag',
|
||
'id',
|
||
'CASCADE'
|
||
);
|
||
}
|
||
|
||
/**
|
||
* {@inheritdoc}
|
||
*/
|
||
public function down()
|
||
{
|
||
// drops foreign key for table `post`
|
||
$this->dropForeignKey(
|
||
'fk-post_tag-post_id',
|
||
'post_tag'
|
||
);
|
||
|
||
// drops index for column `post_id`
|
||
$this->dropIndex(
|
||
'idx-post_tag-post_id',
|
||
'post_tag'
|
||
);
|
||
|
||
// drops foreign key for table `tag`
|
||
$this->dropForeignKey(
|
||
'fk-post_tag-tag_id',
|
||
'post_tag'
|
||
);
|
||
|
||
// drops index for column `tag_id`
|
||
$this->dropIndex(
|
||
'idx-post_tag-tag_id',
|
||
'post_tag'
|
||
);
|
||
|
||
$this->dropTable('post_tag');
|
||
}
|
||
}
|
||
```
|
||
|
||
Począwszy od wersji 2.0.11, nazwy kolumn kluczy obcych dla tabeli węzła są pobierane ze schematu tabel.
|
||
Jeśli tabela nie jest zdefiniowana w schemacie, lub jej klucz główny nie jest ustawiony lub jest kluczem kompozytowym,
|
||
używana jest domyślna nazwa `id`.
|
||
|
||
### Migracje transakcyjne <span id="transactional-migrations"></span>
|
||
|
||
Przy wykonywaniu skomplikowanych migracji bazodanowych, bardzo ważnym jest zapewnienie, aby wszystkie ich operacje
|
||
zakończyły się sukcesem, a w przypadku niepowodzenia nie zostały wprowadzone tylko częściowo, dzięki czemu baza danych
|
||
może zachować spójność. Zalecane jest, aby w tym celu wykonywać operacje migracji wewnątrz [transakcji](db-dao.md#performing-transactions).
|
||
|
||
Najprostszym sposobem implementacji migracji transakcyjnych jest umieszczenie ich kodu w metodach `safeUp()` i `safeDown()`.
|
||
Metody te różnią się od `up()` i `down()` tym, że są wywoływane automatycznie wewnątrz transakcji.
|
||
W rezultacie niepowodzenie wykonania dowolnej z operacji skutkuje automatycznym cofnięciem wszystkich poprzenich udanych
|
||
operacji.
|
||
|
||
W poniższym przykładzie oprócz stworzenia tabeli `news` dodatkowo dodajemy pierwszy wiersz jej danych.
|
||
|
||
```php
|
||
<?php
|
||
|
||
use yii\db\Migration;
|
||
|
||
class m150101_185401_create_news_table extends Migration
|
||
{
|
||
public function safeUp()
|
||
{
|
||
$this->createTable('news', [
|
||
'id' => $this->primaryKey(),
|
||
'title' => $this->string()->notNull(),
|
||
'content' => $this->text(),
|
||
]);
|
||
|
||
$this->insert('news', [
|
||
'title' => 'test 1',
|
||
'content' => 'content 1',
|
||
]);
|
||
}
|
||
|
||
public function safeDown()
|
||
{
|
||
$this->delete('news', ['id' => 1]);
|
||
$this->dropTable('news');
|
||
}
|
||
}
|
||
```
|
||
|
||
Zwróć uwagę na to, że dodając wiele operacji bazodanowych w `safeUp()`, zwykle powinieneś odwrócić kolejność ich
|
||
wykonywania w `safeDown()`. W naszym przykładzie najpierw tworzymy tabelę, a potem dodajemy wiersz w `safeUp()`, natomiast
|
||
w `safeDown()` najpierw kasujemy wiersz, a potem usuwamy tabelę.
|
||
|
||
> Note: Nie wszystkie silniki baz danych wspierają transakcje i nie wszystkie rodzaje komend bazodanowych można umieszczać
|
||
w transakcjach. Dla przykładu, zapoznaj się z rozdziałem dokumentacji MySQL
|
||
[Statements That Cause an Implicit Commit](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). W przypadku
|
||
braku możliwości skorzystania z transakcji, powinieneś użyć `up()` i `down()`.
|
||
|
||
|
||
### Metody pozwalające na dostęp do bazy danych <span id="db-accessing-methods"></span>
|
||
|
||
Bazowa klasa migracji [[yii\db\Migration]] udostępnia zestaw metod, dzięki którym można połączyć się z i manipulować
|
||
bazą danych. Metody te są nazwane podobnie jak [metody DAO](db-dao.md) klasy [[yii\db\Command]].
|
||
Przykładowo metoda [[yii\db\Migration::createTable()]] pozwala na stworzenie nowej tabeli, tak jak
|
||
[[yii\db\Command::createTable()]].
|
||
|
||
Zaletą korzystania z metod [[yii\db\Migration]] jest brak konieczności bezpośredniego tworzenia instancji [[yii\db\Command]],
|
||
a wywołanie każdej z tych metod dodatkowo wyświetli użyteczne informacje na temat operacji bazodanowych i
|
||
czasu ich wykonywania.
|
||
|
||
Poniżej znajdziesz listę wspomnianych wcześniej metod:
|
||
|
||
* [[yii\db\Migration::execute()|execute()]]: wykonywanie komendy SQL
|
||
* [[yii\db\Migration::insert()|insert()]]: dodawanie pojedynczego wiersza
|
||
* [[yii\db\Migration::batchInsert()|batchInsert()]]: dodawanie wielu wierszy
|
||
* [[yii\db\Migration::upsert()|upsert()]]: dodawanie pojedynczego wiersza lub aktualizowanie go, jeśli już istnieje (od 2.0.14)
|
||
* [[yii\db\Migration::update()|update()]]: aktualizowanie wierszy
|
||
* [[yii\db\Migration::delete()|delete()]]: usuwanie wierszy
|
||
* [[yii\db\Migration::createTable()|createTable()]]: tworzenie tabeli
|
||
* [[yii\db\Migration::renameTable()|renameTable()]]: zmiana nazwy tabeli
|
||
* [[yii\db\Migration::dropTable()|dropTable()]]: usuwanie tabeli
|
||
* [[yii\db\Migration::truncateTable()|truncateTable()]]: usuwanie wszystkich wierszy w tabeli
|
||
* [[yii\db\Migration::addColumn()|addColumn()]]: dodawanie kolumny
|
||
* [[yii\db\Migration::renameColumn()|renameColumn()]]: zmiana nazwy kolumny
|
||
* [[yii\db\Migration::dropColumn()|dropColumn()]]: usuwanie kolumny
|
||
* [[yii\db\Migration::alterColumn()|alterColumn()]]: zmiana definicji kolumny
|
||
* [[yii\db\Migration::addPrimaryKey()|addPrimaryKey()]]: dodawanie klucza głównego
|
||
* [[yii\db\Migration::dropPrimaryKey()|dropPrimaryKey()]]: usuwanie klucza głównego
|
||
* [[yii\db\Migration::addForeignKey()|addForeignKey()]]: dodawanie klucza obcego
|
||
* [[yii\db\Migration::dropForeignKey()|dropForeignKey()]]: usuwanie klucza obcego
|
||
* [[yii\db\Migration::createIndex()|createIndex()]]: tworzenie indeksu
|
||
* [[yii\db\Migration::dropIndex()|dropIndex()]]: usuwanie indeksu
|
||
* [[yii\db\Migration::addCommentOnColumn()|addCommentOnColumn()]]: dodawanie komentarza do kolumny
|
||
* [[yii\db\Migration::dropCommentFromColumn()|dropCommentFromColumn()]]: usuwanie komentarza z kolumny
|
||
* [[yii\db\Migration::addCommentOnTable()|addCommentOnTable()]]: dodawanie komentarza do tabeli
|
||
* [[yii\db\Migration::dropCommentFromTable()|dropCommentFromTable()]]: usuwanie komentarza z tabeli
|
||
|
||
> Info: [[yii\db\Migration]] nie udostępnia metod dla kwerendy danych. Wynika to z tego, że zwykle nie jest potrzebne
|
||
wyświetlanie dodatkowych informacji na temat pobieranych danych z bazy. Dodatkowo możesz zawsze użyć potężnego
|
||
[Konstruktora kwerend](db-query-builder.md) do zbudowania i wywołania skomplikowanych kwerend.
|
||
Użycie konstruktora kwerend w migracji może wyglądać następująco:
|
||
>
|
||
> ```php
|
||
> // uaktualnij kolumnę statusu dla wszystkich użytkowników
|
||
> foreach((new Query)->from('users')->each() as $user) {
|
||
> $this->update('users', ['status' => 1], ['id' => $user['id']]);
|
||
> }
|
||
> ```
|
||
|
||
## Stosowanie migracji <span id="applying-migrations"></span>
|
||
|
||
Aby uaktualnić bazę danych do najświeższej wersji jej struktury, należy zastosować wszystkie dostępne nowe migracje,
|
||
korzystając z poniższej komendy:
|
||
|
||
```
|
||
yii migrate
|
||
```
|
||
|
||
Komenda ta wyświetli listę wszystkich migracji, które jeszcze nie zostały zastosowane. Jeśli potwierdzisz, że chcesz je
|
||
zastosować, wywoła ona metodę `up()` lub `safeUp()` dla każdej z migracji na liście, w kolejności ich znaczników czasu.
|
||
Jeśli którakolwiek z migracji nie powiedzie się, komenda zakończy działanie bez stosowania pozostałych migracji.
|
||
|
||
> Tip: Jeśli nie masz dostępu do linii komend na serwerze, wypróbuj rozszerzenie [web shell](https://github.com/samdark/yii2-webshell).
|
||
|
||
Dla każdej udanej migracji komenda doda wiersz do bazy danych w tabeli `migration`, aby oznaczyć fakt zastosowania migracji.
|
||
Pozwoli to na identyfikację, która z migracji została już zastosowana, a która jeszcze nie.
|
||
|
||
> Info: Narzędzie do migracji automatycznie utworzy tabelę `migration` w bazie danych, wskazaną przez opcję
|
||
[[yii\console\controllers\MigrateController::db|db]] komendy. Domyślnie jest to baza danych określona w
|
||
[komponencie aplikacji](structure-application-components.md) `db`.
|
||
|
||
Czasem możesz mieć potrzebę zastosowania tylko jednej bądź kilku nowych migracji, zamiast wszystkich na raz.
|
||
Możesz tego dokonać określając liczbę migracji, które chcesz zastosować uruchamiając komendę.
|
||
Przykładowo, poniższa komenda spróbuje zastosować następne trzy dostępne migracje:
|
||
|
||
```
|
||
yii migrate 3
|
||
```
|
||
|
||
Możesz również dokładnie wskazać konkretną migrację, która powinna być zastosowana na bazie danych, używając komendy
|
||
`migrate/to` na jeden z poniższych sposobów:
|
||
|
||
```
|
||
yii migrate/to 150101_185401 # używając znacznika czasu z nazwy migracji
|
||
yii migrate/to "2015-01-01 18:54:01" # używając łańcucha znaków, który może być sparsowany przez strtotime()
|
||
yii migrate/to m150101_185401_create_news_table # używając pełnej nazwy
|
||
yii migrate/to 1392853618 # używając UNIXowego znacznika czasu
|
||
```
|
||
|
||
Jeśli dostępne są niezaaplikowane migracje wcześniejsze niż ta wyraźnie wskazane w komendzie, zostaną one zastosowane
|
||
automatycznie przed wskazaną migracją.
|
||
|
||
Jeśli wskazana migracja została już wcześniej zaaplikowana, wszystkie zaaplikowane aplikacje z późniejszą datą zostaną
|
||
cofnięte.
|
||
|
||
|
||
## Cofanie migracji <span id="reverting-migrations"></span>
|
||
|
||
Aby odwrócić (wycofać) jedną lub więcej migracji, które zostały wcześniej zastosowane, możesz uruchomić następującą komendę:
|
||
|
||
```
|
||
yii migrate/down # cofa ostatnio dodaną migrację
|
||
yii migrate/down 3 # cofa 3 ostatnio dodane migracje
|
||
```
|
||
|
||
> Note: Nie wszystkie migracje są odwracalne. Próba cofnięcia takiej migracji spowoduje błąd i zatrzyma cały proces.
|
||
|
||
|
||
## Ponawianie migracji <span id="redoing-migrations"></span>
|
||
|
||
Ponawianie migracji oznacza najpierw wycofanie jej, a potem ponowne zastosowanie. Można tego dokonać następująco:
|
||
|
||
```
|
||
yii migrate/redo # ponawia ostatnio zastosowaną migrację
|
||
yii migrate/redo 3 # ponawia ostatnie 3 zastosowane migracje
|
||
```
|
||
|
||
> Note: Jeśli migracja nie jest odwracalna, nie będziesz mógł jej ponowić.
|
||
|
||
## Odświeżanie migracji <span id="refreshing-migrations"></span>
|
||
|
||
Począwszy od Yii 2.0.13 możliwe jest usunięcie wszystkich tabel i kluczy obcych z bazy danych i zastosowanie wszystkich
|
||
migracji od początku.
|
||
|
||
```
|
||
yii migrate/fresh # czyści bazę danych i wykonuje wszystkie migracje od początku
|
||
```
|
||
|
||
## Lista migracji <span id="listing-migrations"></span>
|
||
|
||
Aby wyświetlić listę wszystkich zastosowanych i oczekujących migracji, możesz użyć następujących komend:
|
||
|
||
```
|
||
yii migrate/history # pokazuje ostatnie 10 zastosowanych migracji
|
||
yii migrate/history 5 # pokazuje ostatnie 5 zastosowanych migracji
|
||
yii migrate/history all # pokazuje wszystkie zastosowane migracje
|
||
|
||
yii migrate/new # pokazuje pierwsze 10 nowych migracji
|
||
yii migrate/new 5 # pokazuje pierwsze 5 nowych migracji
|
||
yii migrate/new all # pokazuje wszystkie nowe migracje
|
||
```
|
||
|
||
|
||
## Modyfikowanie historii migracji <span id="modifying-migration-history"></span>
|
||
|
||
Czasem zamiast aplikowania lub odwracania migracji, możesz chcieć po prostu zaznaczyć, że baza danych zostałą już
|
||
uaktualniona do konkretnej migracji. Może się tak zdarzyć, gdy ręcznie modyfikujesz bazę i nie chcesz, aby migracja(e) z
|
||
tymi zmianami zostały potem ponownie zaaplikowane. Możesz to osiągnąć w następujący sposób:
|
||
|
||
```
|
||
yii migrate/mark 150101_185401 # używając znacznika czasu z nazwy migracji
|
||
yii migrate/mark "2015-01-01 18:54:01" # używając łańcucha znaków, który może być sparsowany przez strtotime()
|
||
yii migrate/mark m150101_185401_create_news_table # używając pełnej nazwy
|
||
yii migrate/mark 1392853618 # używając UNIXowego znacznika czasu
|
||
```
|
||
|
||
Komenda zmodyfikuje tabelę `migration` poprzez dodanie lub usunięcie wierszy, aby zaznaczyć, że baza danych ma już
|
||
zastosowane migracje aż do tej określonej w komendzie. Migracje nie zostaną faktycznie zastosowane lub usunięte.
|
||
|
||
|
||
## Dostosowywanie migracji <span id="customizing-migrations"></span>
|
||
|
||
Dostępnych jest kilka opcji pozwalających na dostosowanie komendy migracji do własnych potrzeb.
|
||
|
||
|
||
### Użycie opcji linii komend <span id="using-command-line-options"></span>
|
||
|
||
Komenda migracji ma kilka opcji, które pozwalają na zmianę jej działąnia:
|
||
|
||
* `interactive`: boolean (domyślnie `true`), określa czy przeprowadzić migrację w trybie interaktywnym.
|
||
Jeśli ustawione jest `true`, użytkownik będzie poproszony o potwierdzenie przed wykonaniem określonych operacji.
|
||
Możesz chcieć zmienić to ustawienie na `false`, jeśli komenda ma być używana w tle.
|
||
|
||
* `migrationPath`: string|array (domyślnie `@app/migrations`), określa folder, gdzie znajdują się wszystkie pliki migracji.
|
||
Parametr może być określony jako rzeczywista ścieżka lub [alias](concept-aliases.md).
|
||
Zwróć uwagę na to, że folder musi istnieć, inaczej okmenda może wywołać błąd. Począwszy od wersji 2.0.12 można tutaj
|
||
podać tablicę, aby załadować migracje z wielu źródeł.
|
||
|
||
* `migrationTable`: string (domyślnie `migration`), określa nazwę tabeli w bazie danych, gdzie trzymana będzie historia
|
||
migracji. Tabela będzie automatycznie stworzona, jeśli nie istnieje.
|
||
Możesz również utworzyć ją ręcznie używając struktury `version varchar(255) primary key, apply_time integer`.
|
||
|
||
* `db`: string (domyślnie `db`), określa identyfikator bazodanowego [komponentu aplikacji](structure-application-components.md).
|
||
Reprezentuje on bazę danych, na której będą zastosowane migracje.
|
||
|
||
* `templateFile`: string (domyślnie `@yii/views/migration.php`), określa ścieżkę pliku szablonu, używanego do generowania
|
||
szkieletu plików migracji. Parametr może być określony jako rzeczywista ścieżka lub [alias](concept-aliases.md).
|
||
Plik szablonu jest skryptem PHP, w którym możesz użyć predefiniowanej zmiennej `$className`, aby pobrać nazwę klasy
|
||
migracji.
|
||
|
||
* `generatorTemplateFiles`: array (domyślnie `[
|
||
'create_table' => '@yii/views/createTableMigration.php',
|
||
'drop_table' => '@yii/views/dropTableMigration.php',
|
||
'add_column' => '@yii/views/addColumnMigration.php',
|
||
'drop_column' => '@yii/views/dropColumnMigration.php',
|
||
'create_junction' => '@yii/views/createTableMigration.php'
|
||
]`), określa pliki szablonów do generowania kodu migracji. Po więcej szczegółów przejdź do
|
||
"[Generowanie migracji](#generating-migrations)".
|
||
|
||
* `fields`: tablica definicji kolumn w postaci łańcuchów znaków do wygenerowania kodu migracji. Domyślnie `[]`.
|
||
Format każdej definicji to `NAZWA_KOLUMNY:TYP_KOLUMNY:DEKORATOR_KOLUMNY`. Dla przykładu,
|
||
`--fields=name:string(12):notNull` generuje kolumnę typu "string" o rozmiarze 12, która nie może mieć wartości `null`.
|
||
|
||
Poniższy przykład pokazuje jak można użyć tych opcji.
|
||
|
||
Chcemy zmigrować moduł `forum`, którego pliki migracji znajdują się w folderze `migrations` modułu - używamy następującej
|
||
komendy:
|
||
|
||
```
|
||
# stosuje migracje dla modułu forum w trybie nieinteraktywnym
|
||
yii migrate --migrationPath=@app/modules/forum/migrations --interactive=0
|
||
```
|
||
|
||
|
||
### Konfigurowanie komendy globalnie <span id="configuring-command-globally"></span>
|
||
|
||
Zamiast podawać żmudnie te same opcje za każdym razem, gdy uruchamiamy komendę migracji, można ją skonfigurować w
|
||
konfiguracji aplikacji:
|
||
|
||
```php
|
||
return [
|
||
'controllerMap' => [
|
||
'migrate' => [
|
||
'class' => 'yii\console\controllers\MigrateController',
|
||
'migrationTable' => 'backend_migration',
|
||
],
|
||
],
|
||
];
|
||
```
|
||
|
||
Powyższa konfiguracja powoduje, że z każdym uruchomieniem komendy migracji, tabela `backend_migration` jest używana do
|
||
zapisu historii migracji i nie musisz już określać jej za pomocą opcji linii komend `migrationTable`.
|
||
|
||
|
||
### Migracje w przestrzeni nazw <span id="namespaced-migrations"></span>
|
||
|
||
Począwszy od 2.0.10 możliwe jest używanie przestrzeni nazw w klasach migracji. Możesz zdefiniować listę przestrzeni nazw
|
||
za pomocą [[yii\console\controllers\MigrateController::migrationNamespaces|migrationNamespaces]]. Korzystanie z przestrzeni
|
||
nazw pozwala na łatwe używanie wielu źródeł migracji. Przykładowo:
|
||
|
||
```php
|
||
return [
|
||
'controllerMap' => [
|
||
'migrate' => [
|
||
'class' => 'yii\console\controllers\MigrateController',
|
||
'migrationPath' => null, // wyłącz ścieżkę do folderu migracji, jeśli dodajesz app\migrations na liście poniżej
|
||
'migrationNamespaces' => [
|
||
'app\migrations', // Wspólne migracje dla całej aplikacji
|
||
'module\migrations', // Migracje konkretnego modułu
|
||
'some\extension\migrations', // Migracje konkretnego rozszerzenia
|
||
],
|
||
],
|
||
],
|
||
];
|
||
```
|
||
|
||
> Note: Migracje zaaplikowane z różnych przestrzeni nazw będą dodane do **pojedynczej** historii migracji, przez co np.
|
||
niemożliwym jest zastosowanie lub cofnięcie migracji z tylko wybranej przestrzeni nazw.
|
||
|
||
Wykonując operacje na migracjach z przestrzeni nazw: dodając nowe, odwracając je, itd., należy podać pełną przestrzeń nazw
|
||
przed nazwą migracji. Zwróć uwagę na to, że odwrotny ukośnik (`\`) jest zwykle uważany za znak specjalny linii komend,
|
||
zatem musisz odpowiednio zastosować symbol ucieczki, aby uniknąć błędów konsoli i niespodziewanych skutków komendy.
|
||
Dla przykładu:
|
||
|
||
```
|
||
yii migrate/create app\\migrations\\CreateUserTable
|
||
```
|
||
|
||
> Note: Migracje, których lokalizacja określona jest poprzez
|
||
[[yii\console\controllers\MigrateController::migrationPath|migrationPath]] nie mogą zawierać przestrzeni nazw. Migracje
|
||
w przestrzeni nazw mogą być zaaplikowane tylko jeśli są wymienione we właściwości
|
||
[[yii\console\controllers\MigrateController::migrationNamespaces]].
|
||
|
||
Począwszy od wersji 2.0.12 właściwość [[yii\console\controllers\MigrateController::migrationPath|migrationPath]] pozwala
|
||
również na podanie tablicy wymieniającej wszystkie foldery zawierające migracje bez przestrzeni nazw.
|
||
Zmiana ta została wprowadzona dla istniejących projektów, które używają migracji z wielu lokalizacji, głównie z zewnętrznych
|
||
źródeł jak rozszerzenia Yii tworzone przez innych deweloperów, które z tego powodu nie mogą łatwo być zmodyfikowane, aby
|
||
używać przestrzeni nazw.
|
||
|
||
#### Generowanie migracji w przestrzeni nazw
|
||
|
||
Migracje w przestrzeni nazw korzystają z formatu nazw "CamelCase" `M<YYMMDDHHMMSS><Nazwa>` (przykładowo `M190720100234CreateUserTable`).
|
||
Generując taką migrację pamiętaj, że nazwa tabeli będzie przekonwertowana z formatu "CamelCase" na format "podkreślnikowy".
|
||
Dla przykładu:
|
||
|
||
```
|
||
yii migrate/create app\\migrations\\DropGreenHotelTable
|
||
```
|
||
|
||
generuje migrację w przestrzeni nazw `app\migrations` usuwającą tabelę `green_hotel`, a
|
||
|
||
```
|
||
yii migrate/create app\\migrations\\CreateBANANATable
|
||
```
|
||
|
||
generuje migrację w przestrzeni nazw `app\migrations` tworzącą tabelę `b_a_n_a_n_a`.
|
||
|
||
Jeśli nazwa tabeli zawiera małe i wielkie litery (like `studentsExam`), poprzedź nazwę podkreślnikiem:
|
||
|
||
```
|
||
yii migrate/create app\\migrations\\Create_studentsExamTable
|
||
```
|
||
|
||
To wygeneruje migrację w przestrzeni nazw `app\migrations` tworzącą tabelę `studentsExam`.
|
||
|
||
### Rozdzielenie migracji <span id="separated-migrations"></span>
|
||
|
||
Czasem korzystanie z pojedynczej historii migracji dla wszystkich migracji w projekcie jest uciążliwe. Dla przykładu,
|
||
możesz zainstalować rozszerzenie 'blog', zawierające całkowicie oddzielne funkcjonalności i dostarczające własne migracje,
|
||
które nie powinny wpływać na te dedykowane dla funkcjonalności głównego projektu.
|
||
|
||
Jeśli chcesz, aby część migracji mogła być zastosowana i śledzona całkowicie niezależnie od pozostałych, możesz skonfigurować
|
||
kilka komend migracji, które będą używać różnych przestrzeni nazw i tabeli historii migracji:
|
||
|
||
```php
|
||
return [
|
||
'controllerMap' => [
|
||
// Wspólne migracje dla całej aplikacji
|
||
'migrate-app' => [
|
||
'class' => 'yii\console\controllers\MigrateController',
|
||
'migrationNamespaces' => ['app\migrations'],
|
||
'migrationTable' => 'migration_app',
|
||
'migrationPath' => null,
|
||
],
|
||
// Migracje dla konkretnego modułu
|
||
'migrate-module' => [
|
||
'class' => 'yii\console\controllers\MigrateController',
|
||
'migrationNamespaces' => ['module\migrations'],
|
||
'migrationTable' => 'migration_module',
|
||
'migrationPath' => null,
|
||
],
|
||
// Migrations dla konkretnego rozszerzenia
|
||
'migrate-rbac' => [
|
||
'class' => 'yii\console\controllers\MigrateController',
|
||
'migrationPath' => '@yii/rbac/migrations',
|
||
'migrationTable' => 'migration_rbac',
|
||
],
|
||
],
|
||
];
|
||
```
|
||
|
||
Zwróć uwagę na to, że teraz, aby zsynchronizować bazę danych, musisz uruchomić kilka komend zamiast jednej:
|
||
|
||
```
|
||
yii migrate-app
|
||
yii migrate-module
|
||
yii migrate-rbac
|
||
```
|
||
|
||
|
||
## Migrowanie wielu baz danych <span id="migrating-multiple-databases"></span>
|
||
|
||
Domyślnie migracje są stosowane do jednej bazy danych określonej przez
|
||
[komponent aplikacji](structure-application-components.md) `db`. Jeśli chcesz, aby były zastosowane do innej bazy, musisz
|
||
zdefiniować opcję `db` w linii komend, jak poniżej,
|
||
|
||
```
|
||
yii migrate --db=db2
|
||
```
|
||
|
||
Ta komenda zastosuje migracje do bazy `db2`.
|
||
|
||
Czasem konieczne jest, aby zastosować *niektóre* migracje do jednej bazy, a inne do drugiej. Aby to uzyskać, podczas
|
||
implementacji klasy migracji należy bezpośrednio wskazać identyfikator komponentu bazy danych, który migracja ma użyć,
|
||
jak poniżej:
|
||
|
||
```php
|
||
<?php
|
||
|
||
use yii\db\Migration;
|
||
|
||
class m150101_185401_create_news_table extends Migration
|
||
{
|
||
public function init()
|
||
{
|
||
$this->db = 'db2';
|
||
parent::init();
|
||
}
|
||
}
|
||
```
|
||
|
||
Ta migracja będzie zastosowana do bazy `db2`, nawet jeśli w opcjach komendy określona będzie inna baza.
|
||
Zwróć uwagę na to, że historia migracji będzie uaktualniona wciąż w bazie danych określonej przez opcję `db` linii komend.
|
||
|
||
Jeśli masz wiele migracji korzystających z tej samej bazy danych, zalecane jest utworzenie bazowej klasy migracji z
|
||
powyższym kodem metody `init()`, a następnie dziedziczenie po niej w każdej kolejnej migracji.
|
||
|
||
> Tip: Oprócz ustawiania właściwości [[yii\db\Migration::db|db]], możesz również operować na różnych bazach poprzez
|
||
tworzenie nowych połączeń bazodanowych w klasach migracji, a następnie korzystanie z [metod DAO](db-dao.md) i tych
|
||
połączeń.
|
||
|
||
Inną strategią migracji wielu baz danych jest utrzymywanie migracji dla różnych baz w różnych folderach migracji. Dzięki
|
||
temu możesz te bazy migrować w osobnych komendach:
|
||
|
||
```
|
||
yii migrate --migrationPath=@app/migrations/db1 --db=db1
|
||
yii migrate --migrationPath=@app/migrations/db2 --db=db2
|
||
...
|
||
```
|
||
|
||
Pierwsza komenda zastosuje migracje z folderu `@app/migrations/db1` na bazie `db1`, druga migracje z folderu
|
||
`@app/migrations/db2` na bazie `db2`, itd.
|