Laravel 10.x pamoka. Migracijos

Migracijos reikalingos tam, kad perduodant programinį kodą kitiems programuotojams nereikėtų atskirai daryti duomenų bazės eksporto. Visa informacija apie duomenų bazės pakeitimus bus saugoma migracijose ir kiekvienas programuotojas galės jas lengvai valdyti su Laravel komandomis. Todėl jūs neturėtume atlikinėti pakeitimų rankiniu būdu per phpMyAdmin įrankį.
Duomenų bazėje saugosime tokias lenteles: books (knygos), publishers (leidyklos), genres (žanrai), authors (autoriai), books_authors (papildoma lentelė N:N ryšiui nustatyti tarp knygų ir autorių, kadangi viena knyga gali turėti daugiau nei vieną autorių) ir orders (knygų užsakymai). Atitinkamai komandinėje eilutėje kiekvienai lentelei sukursime tokias migracijas:
php artisan make:migration create_publishers_table --create=publishers
php artisan make:migration create_genres_table --create=genres
php artisan make:migration create_books_table --create=books
php artisan make:migration create_authors_table --create=authors
php artisan make:migration create_books_authors_table --create=books_authors
php artisan make:migration create_orders_table --create=orders
Taip pat sukursime vieną testinę lentelę, kad pademonstruoti lentelės ištrynimą:
php artisan make:migration create_test_table --create=test
Kataloge ../library/database/migrations/ rasite visas naujai sukurtas migracijas:
migrations
Kiekvienoje migracijoje yra metodas up(), kurį reikia atitinkamai papildyti lentelių laukais.
Lentelės publishers up() metodas:
public function up(): void
    {
        Schema::create('publishers', function (Blueprint $table) {
            $table->id('id');
            $table->string('title');
            $table->string('website')->nullable(); // nullable reiškia, kad laukas nėra privalomas ir gali būti tuščias
            $table->string('address')->nullable();
            $table->string('phone')->nullable();
            $table->timestamps();
        });
    }
Lentelės genres up() metodas:
public function up(): void
    {
        Schema::create('genres', function (Blueprint $table) {
            $table->id('id');
            $table->string('title');
            $table->timestamps();
        });
    }
Lentelės books up() metodas:
public function up(): void
    {
        Schema::create('books', function (Blueprint $table) {
            $table->id('id');
            $table->string('title', 100);
            $table->string('isbn', 13);
            $table->year('year')->unsigned();
            $table->unsignedSmallInteger('pages');
            $table->unsignedTinyInteger('quantity');
            $table->unsignedDecimal('price', 8, 2);
            $table->string('cover');
            $table->foreignId('publisher_id');
            $table->foreignId('genre_id');
            $table->timestamps();

            $table->foreign('publisher_id')->references('id')->on('publishers');
            $table->foreign('genre_id')->references('id')->on('genres');
        });
    }
Metodas foreign() leidžia nustatyti ryšį 1:N tarp lentelių. Šiuo atveju yra parašyti du foreign() metodai, kurių vienas apjungia lentelę books su lentele publishers, o kitas - lentelę books su lentele genres. Tarp šių lentelių naudojamas ryšys 1:N, nes įsivaizduosim, kad viena knyga gali turėti tik vieną leidėją ir viena knyga gali būti priskirta tik vienam žanrui.
Lentelės authors up() metodas:
public function up(): void
    {
        Schema::create('authors', function (Blueprint $table) {
            $table->id('id');
            $table->string('firstname');
            $table->string('middlename')->nullable();
            $table->string('lastname');
            $table->boolean('gender')->unsigned(); //bus sukurtas laukas tinyint(1), šiame lauke saugosime tik dvi galimas reikšmes: 1 - vyras, 2 - moteris
            $table->timestamps();
        });
    }
Lentelės books_authors up() metodas:
public function up(): void
    {
        Schema::create('books_authors', function (Blueprint $table) {
            $table->id('id');
            $table->foreignId('book_id');
            $table->foreignId('author_id');
            $table->timestamps();

            $table->foreign('book_id')->references('id')->on('books');
            $table->foreign('author_id')->references('id')->on('authors');
        });
    }
Įprastai reliacinėse duomenų bazėse ryšys N:N yra aprašomas per tarpinę lentelę. Šiuo atveju mums reikia nustatyti ryšį N:N tarp lentelių books ir authors, nes viena knyga gali turėti daug autorių, o vienas autorius gali būti parašęs daug knygų.
Lentelės orders up() metodas:
public function up(): void
    {
        Schema::create('orders', function (Blueprint $table) {
            $table->id('id');
            $table->foreignId('book_id');
            $table->foreignId('user_id');
            $table->timestamp('taken')->nullable();
            $table->timestamp('returned')->nullable();
            $table->timestamps();

            $table->foreign('book_id')->references('id')->on('books');
            $table->foreign('user_id')->references('id')->on('users');
        });
    }
Lentelė orders taip pat sukuria ryšį N:N tarp lentelių books ir users, nes vieną ir tą pačią knygą gali paiimti daug naudotojų (tik skirtingu metu) ir vienas naudotojas vieno užsakymo metu gali paiimti daug knygų.
Sukūrus visų lentelių migracijas komandinėje eilutėje jas įvykdykite, kad jos atsirastų MySQL duomenų bazėje:
php artisan migrate
Naršyklės adreso lauke įveskite phpMyAdmin įrankio adresą http://localhost/phpmyadmin ir atsidarykite savo sukurtą duomenų bazę (pvz., library). Dabar joje matysite visas per migracijas sukurtas lenteles.

Laukų pakeitimai, įterpimai ir pašalinimai

Kartais reikia lentelėse pakeisti lauko ilgį, lauko pavadinimą, įterpti naują lauką ar pašalinti esamą. Tokiu atveju nerekomenduojama pakeitimų atlikti pačioje MySQL duomenų bazėje. Teisingas sprendimas būtų atitinkamai sukurti naujas migracijas su pakeitimais. Atlikime keletas iš jų.
Norint atlikti duomenų bazės struktūros pakeitimą, projekte reikia įdiegti Doctrine DBAL biblioteką. Komandinėje eilutėje įveskite komandą ir ją įvykdykite:
composer require doctrine/dbal

Lauko ilgio pakeitimas

Norint pakeisti lauko ilgį, sukurkime naują migraciją (migracijos pavadinimą galit keisti savo nuožiūra):
php artisan make:migration change_book_title_length_to_books_table --table=books
Atsidarykite migraciją ir up() metode įrašykite tokį programinį kodą:
Schema::table('books', function (Blueprint $table) {
    $table->string('title', 255)->change();
});

Lauko pavadinimo pakeitimas

Norint pakeisti lauko pavadinimą, sukurkime naują migraciją (migracijos pavadinimą galit keisti savo nuožiūra):
php artisan make:migration change_author_names_to_authors_table --table=authors
Atsidarykite migraciją ir up() metode įrašykite tokį programinį kodą:
Schema::table('authors', function (Blueprint $table) {
    $table->renameColumn('firstname', 'first_name');
    $table->renameColumn('middlename', 'middle_name');
    $table->renameColumn('lastname', 'last_name');
});

Naujo lauko įterpimas

Norint įterpti naują lauką, sukurkime naują migraciją (migracijos pavadinimą galit keisti savo nuožiūra):
php artisan make:migration add_description_field_to_books_table --table=books
Atsidarykite migraciją ir up() metode įrašykite tokį programinį kodą:
Schema::table('books', function (Blueprint $table) {
    $table->text('description')->after('title')->nullable();
});

Esamo lauko pašalinimas

Norint pašalinti esamą lauką, sukurkime naują migraciją (migracijos pavadinimą galit keisti savo nuožiūra):
php artisan make:migration delete_address_field_from_publishers_table --table=publishers
Atsidarykite migraciją ir up() metode įrašykite tokį programinį kodą:
Schema::table('publishers', function (Blueprint $table) {
    $table->dropColumn('address');
});
Taip pat galima pašalinti keletą laukų vienu metu:
Schema::table('publishers', function (Blueprint $table) {
    $table->dropColumn(['address','phone']);
});

Lentelės pavadinimo pakeitimas

Norint pakeisti lentelės pavadinimą, sukurkime naują migraciją (migracijos pavadinimą galit keisti savo nuožiūra):
php artisan make:migration change_genres_to_categories --table=genres
Atsidarykite migraciją ir up() metode įrašykite tokį programinį kodą:
Schema::table('genres', function (Blueprint $table) {
    Schema::rename('genres', 'categories');
});

//taip pat pakeisime ir genre_id lauko pavadinimą lentelėje books
Schema::table('books', function (Blueprint $table) {
    $table->renameColumn('genre_id', 'category_id');
});

Lentelės pašalinimas

Norint pašalinti lentelę, sukurkime naują migraciją (migracijos pavadinimą galit keisti savo nuožiūra):
php artisan make:migration delete_test_table --table=test
Atsidarykite migraciją ir up() metode įrašykite tokį programinį kodą:
Schema::drop('test');
arba tokį, jei norite, kad prieš ištrinant lentelę būtų patikrinta ar tokia buvo:
Schema::dropIfExists('test');
Nepamirškite sukūrus migracijas jas įvykdyti:
php artisan migrate
Daugiau apie migracijas skaitykite oficialioje Laravel 10.x dokumentacijoje, skiltyje Database: Migrations.

Paskutinį kartą puslapis keistas 2023-05-10

© Joana Katina 2016-2024. Visos teisės saugomos