Adatbázis hozzáférés 2. rész - SQLite és Microsoft SQL Server

Attila | 2022. 02. 20. 21:18 | Olvasási idő: 4 perc

Címkék: #Adatbázis (Database) #Laravel #Microsoft SQL #MySQL #SQLite

Ahogy ennek a részsorozatnak az 1. részében ígértem, megnézzük, hogy hogyan lehet a MySQL-en kívül más adatbázis-kezelőkhöz hozzáférni az alkalmazásunkból. A "pehelykönnyű" SQLite és a "nagyágyúnak számító" Microsoft SQL Server lesz ehhez a segítségünkre. Hosszú bejegyzés következik, érdemes odafigyelni minden lépésre, mert könnyű lesz "eltévedni".
db_sqlite_mssql_v2

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.