A projekt, amelyhez visszanyúlunk a Github-ról clone-ozott Laravel Blog projekt
lesz. Módosítani fogjuk úgy az alkalmazásunkat, hogy ne a MySQL
szerveren, hanem helyette először egy SQLite fájlban, majd utána pedig a
Microsoft SQL szerverén történjen meg az adatok tárolása.
Azért
kezdjük az SQLite-tal, mert annak a használata egy picit egyszerűbb egy
Laravel projekt esetén. Aki esetleg nem tudná, vagy nem ismerné az
SQLite adatbáziskezelőt, annak a magyar wikipédia
(sic!) egy jó kiindulási pont lehet. Nekünk első körben elegendő annyit
tudni, hogy ez egy fájl alapú adatbázis tárolást nyújt a számunkra és
nem kell hozzá különböző programokat telepítenünk, hogy relációs
adatbázisokat legyünk képesek tárolni és menedzselni a gépünkön.
Ahogy
az a config mappában lévő database.php konfigurációs fájlban is
látszik, szerencsére az SQLite használatához van a Laravel-nek egy
driver-e, amivel könnyedén el tudja érni és menedzselni tudja az ilyen
adatbázisokat.
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
Itt kiemelte a database.php-ből a releváns részletet. Látható, hogy
itt nem kell majd annyi mindent beállítanunk, mint a MySQL kapcsolat
esetén és alapértelmezetten a Laravel projektünk database mappájában fog
keresni egy database.sqlite fájlt a rendszer, hacsak felül nem írjuk mi
ezt az attribútumot az .env fájlunkban. Nekünk ez első körben teljesen
jó, úgyhogy hozzuk létre ezt az új, database.sqlite nevű fájlt a
database mappában.
Az .env fájlból kitörölhetjük a nem szükséges
adatbázisokat érintő attribútumokat és csak az SQLite specifikus részt
hagyjuk meg benne.
DB_CONNECTION=sqlite
DB_HOST=127.0.0.1
Következhet a migráció! Viszont azért lássuk azt, hogy egy picit
nagyobb fába vágjuk a fejszénket, hiszen számos adattábla tartozik ehhez
az alkalmazáshoz és bőven előfordulhat, hogy vannak benne olyan MySQL
specifikus részek, amelyek egy másik adatbázis-kezelőben egy picit
másképp működnek. No, de majd megpróbáljuk ezeket orvosolni, ha
ténylegesen felmerülnek. Ha elmentettük az új .env fájlunkat, akkor
utána következhet a parancs futtatása a terminal-ban:
php artisan migrate
Jónéhány
fájl - és ebből kifolyólag az adattábláik - migrálására kerülnek az
SQLite adatbázisunkba, azonban sajnos kapunk is hibát:
SQLSTATE[HY000]:
General error: 1 Cannot add a NOT NULL column with default value NULL
(SQL: alter table "posts" add column "slug" varchar not null)
A
hiba javításához nyissuk meg a hibaüzenet feletti legutolsó fájlt, ezek
a fájlok a database mappán belül a migrations mappában vannak, az
érintett fájl pedig nálam ez: 2017_04_16_092512_add_slug_to_posts.php
Kiemelem alább, hogy hogyan kell orvosolni a hibát, amit a fenti üzenet
jelzett (az utolsó nyíltól kezdve van a javítás):
$table->string('slug')->unique()->after('title')->default('');
Mivel már részben migrálódtak az adatbázisba az adattábláink, de
sajnos a teljes migrációs folyamat nem tudott végigmenni, mert hibát
kaptunk, emiatt adjuk ki a következő parancsot, hogy "újrahúzzuk" a
teljes adatbázis szerkezetet:
php artisan migrate:fresh
Most
már tovább jutottunk (a fájlnevekben a dátumokra érdemes figyelni) a
migrációs folyamatban, mint korábban, ebből látszik, hogy a korábbi
hibát tényleg sikerült kijavítanunk.
A következő problémás fájlunk 2018_03_22_214952_drop_media_table.php és hibaüzenetünk:
SQLite doesn't support dropping foreign keys (you would need to re-create the table).
Itt
sajnos az SQLite azt jelzi nekünk, hogy ő nem támogatja az adatbázisban
az idegen kulcsok eldobását. Ezt egy egyszerű feltételvizsgálattal
fogjuk megoldani a 2018_03_22_214952_drop_media_table.php fájlban,
szúrjuk be az if-fel kezdődő sort a dropForeign-es utasítás elé:
if (\DB::getDriverName() !== 'sqlite')
$table->dropForeign(['thumbnail_id']);
Újra futtathatjuk a php artisan migrate:fresh parancsot és most már hiba
nélkül végigfut a teljes migrációs folyamat, az adattáblák pedig
bekerültek a database mappában lévő database.sqlite fájlba. Sajnos
viszont ez egy bináris fájl, így nem tudjuk megnyitni a VSCode-ban
simán, de létezik hozzá kiterjesztés, ami már segíthet nekünk. Itt
szintén megjegyezném, hogy számos egyéb SQLite adatbáziskezelő
alkalmazás létezik, sőt még a VSCode-hoz is tudunk kiterjesztéseket
telepíteni, amelyekkel könnyedén menedzselhető ez az adatbázistípus. Én
szeretem, hogy ha van egy külön menedzselő programom ehhez, úgyhogy
telepítettem hozzá a DB Browser for SQLite alkalmazást innen.
Megnyitva a DB Browser-t, ki tudom tallózni az érintett database.sqlite
fájlomat és már mutatja is a táblaszerkezetét az alkalmazás:
Láthatjuk,
hogy ugyanazok a tábláink vannak, mint korábban a MySQL adatbázis
esetén voltak és felhívnám a figyelmet arra, hogy ehhez semmilyen
különleges programozási feladatot, vagy SQL utasításokat sem kellett
írnunk. Két SQLite-specifikus dolgot kellett megváltoztatni a 17 tábla
és a 19 egyéb tábla/mezőkényszer megvalósításához.
Következhet a Microsoft SQL Server-re való migrálás!
A
Laravel alkalmazásunk ugyanaz lesz, mint amibe az SQLite-os
módosításokat is elvégeztük az imént. MS SQL Server-re viszont biztosan
szükségünk van, de semmi probléma, ezek is beszerezhetők ingyen,
méghozzá a Developer és az Express verzió is. Itt érdemes keresgélni a "Download now" feliratú gombokat: https://www.microsoft.com/en-us/sql-server/sql-server-downloads
Nálam
egy Developer verzió van fenn a gépemen, úgyhogy én ennek kapcsán tudok
tapasztalatokat megosztani. Ha pedig már ezt felraktam, akkor
telepítettem is hozzá egy SQL Server Management Studio-t innen,
amellyel hatékonyan lehet kezelni az adatbázisokat. Ennek a
bejegyzésnek nem témája, hogy hogyan is kell Microsoft SQL Server-t vagy
a Management Studio-t telepíteni, úgyhogy ettől eltekintenék és csak
arra koncentrálok, hogy a Laravel alkalmazásunkkal, hogy tudjuk majd
elérni az SQL Server-en létrehozott adatbázist... tegyük is meg ezt a
létrehozást: a Management Studio-ban grafikusan, kattintgatásokkal is
megtehetnénk, de én egy New Query ablakban adom ki a következő utasítást
(MySQL engedte, hogy a szavak között kötőjel legyen, ezt az MS SQL nem
engedi, úgyhogy itt aláhúzást teszek a szavak közé):
CREATE DATABASE laravel_blog_db;
Mivel most "Windows Authentication" módon vagyok bejelentkezve a
Management Studio-ba, ezért létrehozok egy olyan felhasználót, aki majd
tulajdonosa lesz ennek az újonnan létrehozott laravel_blog_db
adatbázisnak. A Security fő mappában a Logins mappára jobb egérgombbal
kattintva tudok "New login..."-t kiválasztani. "Login name"-nek adjuk
meg például azt, hogy laraveluser, "SQL Server authentication"-t
válasszunk a következő részben, majd adjunk meg egy aránylag hosszú
jelszót (például: ASDFqwer1234), majd az "Enforce Password
expiration"-nél vegyük ki a pipát.
A
"User Mapping" bal oldali menüpontban végezzük el a következő beállítást:
laravel_blog_db adatbázis kiválasztása (pipálással), majd alul a
"db_owner"-t pipáljuk ki és nyomhatunk alul az OK gombra.
Ellenőrzésként
megtehetjük, hogy az "Object Explorer"-ben a "Databases"-t nyissuk le, majd
plusszozzuk ki a laravel_blog_db-t és a "Security"-n belül a "Users"
mappában ott kell lennie az imént hozzárendelt laraveluser
felhasználónak.
Ezzel
az adatbázis készen is áll arra, hogy fogadja a migrációs fájlok
futásának eredményeit, vagyis az adattáblákat eltárolásra ezzel az új
felhasználóval. Vannak viszont olyan beállítások, amelyeket el kell
végeznünk akkor, ha egy PHP-alapú programból szeretnénk elérni a
Microsoft SQL Server-ét. Ezeket fogjuk most megtenni.
Fontos megjegyezni,
hogy én XAMPP szervert használok, ezzel települt fel a PHP fordítóm is,
méghozzá a 7.4-es verziójú PHP, úgyhogy fogom elmagyarázni a különböző
konfigurációs beállításokat, de nyilván, hogy ha valaki ennél eltérő
verziójú PHP-t használ, akkor annak majd az adott verziójú
mappákat/fájlokat kell érintenie.
Hozzuk be ezt a weboldalt: https://github.com/Microsoft/msphpsql/releases
Én
legörgetek és a Windows-7.4.zip fájlt letöltöm, majd utána meg is
nyitom. Mivel nekem 64 bites operációs rendszerem van, ezért a zip
fájlban azt a mappát választom ki.
Ez
a négy fájl van a mappában. Nekünk arra van szükségünk, amelynél a
fájlnév "_ts"-re végződik a .dll kiterjesztés előtt. Ezt a két fájlt
kellene átmásolni a C:\xampp\php\ext mappába, ide (a két érintett fájl
van kiemelve, felül pedig látszik a mappa neve is):
Ha
ez megvan, akkor elvégezhetjük a további beállításokat ehhez. Nyissuk
meg szövegszerkesztővel a C:\xampp\php mappában a php.ini nevű fájlt. Az
ini fájlban a ; (pontosvesszővel) kezdődő sorok megjegyzések. Keressük
meg a "Dynamic Extensions" szekciót, nálam a 885. sorban van, tehát
valahol akörül érdemes keresni. Ennek a szekciónak a végére, de még a
"Modul Settings" szekció elé érdemes létrehozni ennek a két új fájlnak,
kiterjesztésének a beemelését:
extension=php_pdo_sqlsrv_74_ts.dll
extension=php_sqlsrv_74_ts.dll
Ha
ezt megcsináltuk, mentsük el a php.ini fájlt, majd indítsuk újra a
XAMPP szerverünket, hogy érvényre tudjanak jutni ezek a beállítások.
Nincs
más hátra, mint visszatérni a Laravel projektünkhöz, annak is az .env
fájljához és beállítsuk az MS SQL Server-nek megfelelő kapcsolódási
paramétereket.
DB_CONNECTION=sqlsrv
DB_HOST=127.0.0.1
DB_PORT=1433
DB_DATABASE=laravel_blog_db
DB_USERNAME=laraveluser
DB_PASSWORD=ASDFqwer1234
Ezután mentsük el az .env fájlt és futtathatjuk a már ismert parancsot: php artisan migrate
Elindult
a migrációs fájlok feldolgozása, de most is hasonló szituációba
futottunk bele, mint az SQLite esetében, nem futott végig a migrációs
folyamat, hibába ütközött. Megint meg fogjuk oldani egyesével ezeket a
hibákat, amik abból adódnak, hogy a projekt alapértelmezett
adatbáziskezelője, a MySQL, amely egy kicsit eltér a most alkalmazni
kívánt MS SQL-től.
A hiba a 2016_12_19_201351_create_comments_table.php fájllal van.
Introducing
FOREIGN KEY constraint 'comments_post_id_foreign' on table 'comments'
may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION
or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. (SQL:
alter table "comments" add constraint "comments_post_id_foreign" foreign
key ("post_id") references "posts" ("id") on delete cascade)
A kijavításához egyetlen sort kell módosítanunk:
$table->foreign('author_id')->references('id')->on('users')->onDelete('no action');
Futtassuk a parancsot, hogy a migrált táblákat is újra migrálja a problémák elkerülése végett: php artisan migrate:fresh
Ezzel
az egy javítással meg is oldottunk mindent, több műveletre nincsen
szükség. Itt vannak a táblák az MS SQL Server-en lévő adatbázisunkban:
A php artisan db:seed
parancs kiadásával pedig az adatbetöltés is tökéletesen működik,
ellenőrizhetjük, hogy a users táblába bekerült-e a felhasználó, de akár a
php artisan serve paranccsal magát a weboldalt is tudjuk ellenőrizni.
Összefoglalásként
elmondható tehát, hogy egy meglévő, működő projekt 17 adattábláját és 19 tábla/mezőkényszerét különösebben nagyobb probléma nélkül át
tudtuk tökéletesen ültetni a MySQL-ről akár SQLite alapú, akár Microsoft
SQL Server alapú adatkiszolgálóra.