Címkék: #Adatbázis (Database) #Laravel #Microsoft SQL #MySQL #SQLite
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'); // 'cascade' volt --> 'no action' lett
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.