Ako používať Sequelize s Node.js a MySQL
Autor vybral Fond otvoreného internetu/Slobodnej reči na prijatie daru ako súčasť programu Píš pre dary.
Úvod
Sequelize je objektovo-relačný mapper založený na Node.js, ktorý uľahčuje prácu s databázami MySQL, MariaDB, SQLite, PostgreSQL a ďalšími. Objektovo-relačný mapper vykonáva funkcie, ako je spracovanie databázových záznamov tým, že dáta predstavuje ako objekty. Sequelize má výkonný migračný mechanizmus, ktorý dokáže transformovať existujúce databázové schémy na nové verzie. Celkovo Sequelize poskytuje vynikajúcu podporu pre synchronizáciu databáz, eager loading, asociácie, transakcie a databázové migrácie, pričom skracuje čas vývoja a zabraňuje SQL injekciám.
V tomto návode nainštalujete a nakonfigurujete Sequelize s MySQL vo vašom lokálnom vývojovom prostredí. Následne budete používať Sequelize na vytváranie databáz a modelov, ako aj na vykonávanie operácií insert, select a delete. Potom vytvoríte Sequelize asociácie pre vzťahy jeden k jednému, jeden k mnohým a mnoho k mnohým. Na záver vytvoríte Sequelize surové dotazy pre nahraďovanie polí a objektov. Okrem týchto základov návod tiež pokrýva bezpečnú konfiguráciu databázy pomocou environmentálnych premenných, bezpečné riadenie zmien schémy cez migrácie a osvedčené postupy pri riešení problémov a optimalizácii výkonu.
Nasadzujte svoje frontendové aplikácie z GitHubu pomocou platformy Linux-Console.net App. Nechajte Linux-Console.net zaoberať sa škálovaním vašej aplikácie.
Hlavné body:
- Sequelize poskytuje jednoduchý spôsob, ako pracovať s MySQL pomocou modelov namiesto priamoho SQL, čo robí operácie s databázou jednoduchšími a lepšie organizovanými.
- Ukladanie prihlasovacích údajov do databázy do premenných prostredia udržiava citlivé informácie v bezpečí a mimo správy verzií.
- Používanie migrácií na aktualizáciu schémy je bezpečnejšie ako spoliehať sa na
sequelize.sync(), najmä v produkčných prostrediach. - Sequelize uľahčuje definovanie vzťahov jeden k jednému, jeden k mnohým a mnoho k mnohým medzi modelmi.
- Surové SQL dotazy sa stále dajú používať, keď potrebujete väčšiu kontrolu alebo lepší výkon pri zložitých databázových operáciách.
- Najbežnejšie problémy so Sequelize, ako sú zlyhania pripojenia alebo chyby migrácie, je možné vyriešiť kontrolou premenných prostredia, prehliadnutím záznamov a použitím nástrojov MySQL, ako sú
EXPLAINaSHOW PROCESSLIST. - Výkon je možné zlepšiť optimalizáciou dotazov, pridávaním správnych indexov, ladením pripojovacích bazénov a ukladaním často používaných údajov do vyrovnávacej pamäte.
- Testovanie migrácií, pridávanie spracovania chýb a monitorovanie výkonu databázy pomáhajú udržiavať aplikácie Sequelize spoľahlivé a pripravené do produkcie.
Predpoklady
Na dokončenie tohto tutoriálu budete potrebovať:
- Vývojové prostredie bežiace na Node.js. Ak ho chcete nastaviť, postupujte podľa tutoriálu Ako nainštalovať Node.js a vytvoriť lokálne vývojové prostredie pre váš operačný systém.
- MySQL nainštalovaný vo vašom pracovnom prostredí. Postupujte podľa návodu Ako nainštalovať MySQL pre vaše prostredie, vrátane krokov na vytvorenie používateľa.
- Znalosť JavaScriptu a MySQL dotazov, ktoré môžete rozvíjať prostredníctvom série Ako programovať v JavaScripte a tutoriálu Úvod do dotazov v MySQL.
- Základné pochopenie konceptov relačných databáz, ktoré nájdete v návode Pochopenie relačných databáz.
Tento návod bol testovaný na verzii Node.js v24.11.1 a verzii npm 11.6.2.
Inštalácia a konfigurácia Sequelize
V tomto kroku nainštalujete Sequelize a vytvoríte pripojenie k vašej MySQL databáze. Najprv vytvoríte aplikáciu Node.js. Potom nainštalujete Sequelize, nakonfigurujete MySQL databázu a vyviniete jednoduchú aplikáciu.
Inštalácia Sequelize
Začnite vytvorením priečinka projektu. V tomto príklade môžete použiť hello-world. Keď je priečinok vytvorený, prejdite do priečinka pomocou terminálu:
mkdir hello-world
cd hello-worldPotom vytvorte ukážkovú aplikáciu Node.js pomocou nasledujúceho príkazu:
npm initĎalej budete vyzvaní na zodpovedanie niekoľkých úvodných otázok. Pre svoju konfiguráciu použite nasledujúci výstup. Stlačte ENTER pre použitie zobrazených predvolených hodnôt a nezabudnite nastaviť hlavnú vstupnú bod ako server.js. Týmto sa vytvorí štruktúra projektu, ktorú je ľahké udržiavať.
Výstup bude vyzerať nasledovne, čo vyplní súbor package.json:
{
"name": "hello-world",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}Ďalej vytvorte prázdny súbor server.js vo vnútri priečinka projektu:
touch server.jsPo dodržaní predchádzajúcich krokov bude vaša konečná štruktúra priečinkov vyzerať takto:
hello-world/
├─ package.json
├─ server.js
Teraz môžete nainštalovať Sequelize pomocou nasledujúceho príkazu:
npm i sequelizePo týchto aktualizáciách súbor package.json teraz vyzerá takto:
{
"name": "hello-world",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"sequelize": "^6.37.7"
}
}V sekcii dependencies teraz uvidíte závislosť Sequelize.
Nastavili ste projekt a nainštalovali Sequelize. Ďalej vytvoríte ukážkovú databázu, ku ktorej sa pripojíte.
Vytváranie vzorovej databázy
Ako súčasť požiadaviek ste nainštalovali a nakonfigurovali MySQL, čo zahŕňalo vytvorenie používateľa. Teraz vytvoríte prázdnu databázu.
Na to sa musíte najprv prihlásiť do svojej inštancie MySQL. Ak ju spúšťate vzdialene, môžete použiť svoj preferovaný nástroj. Ak používate lokálne spustenú inštanciu MySQL, môžete použiť nasledujúci príkaz, pričom your_username nahradíte svojim používateľským menom MySQL:
mysql -u your_username -p-u je používateľské meno a možnosť -p sa používa, ak je účet chránený heslom.
Server MySQL vás požiada o heslo k databáze. Zadajte svoje heslo a stlačte ENTER.
Keď sa prihlásite, vytvorte databázu s názvom hello_world_db pomocou nasledujúceho príkazu:
CREATE DATABASE hello_world_db;Ak chcete overiť, či ste databázu vytvorili úspešne, môžete použiť tento príkaz:
SHOW DATABASES;
Váš výstup bude podobný tomuto:
+--------------------+
| Database |
+--------------------+
| hello_world_db |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+Po vytvorení ukážkovej databázy sa odpojte od servera MySQL:
mysql> QUITTeraz musíte nainštalovať manuálny ovládač pre vašu vybranú databázu. Keďže Sequelize poskytuje iba funkcie ORM, neobsahuje zabudované ovládače databázy. Preto budete musieť nainštalovať ovládače podľa vášho výberu. Aby ste to urobili, prejdite do adresára projektu pomocou terminálu a nainštalujte ovládač MySQL do projektu pomocou nasledujúceho príkazu:
npm install --save mysql2V tomto prípade používate ovládač pre MySQL.
Poznámka: Keďže tento tutoriál používa MySQL ako databázu, používate ovládač pre ňu. V závislosti od vašej databázy môžete ovládač nainštalovať manuálne takto:
npm install --save pg pg-hstore # Postgresnpm install --save mysql2npm install --save mariadbnpm install --save sqlite3npm install --save tedious # Microsoft SQL Server
Teraz, keď máte ukážkovú databázu, môžete vytvoriť svoju prvú aplikáciu Sequelize s pripojením k databáze.
Pripojenie k databáze MySQL
V tejto sekcii pripojíte aplikáciu Node.js k databáze MySQL pomocou Sequelize.
Na pripojenie k databáze otvorte súbor server.js na úpravu pomocou nano alebo vášho obľúbeného editoru kódu:
nano server.jsTu vytvoríte databázové pripojenie vo svojej aplikácii pomocou inštancie Sequelize. V metóde new Sequelize() odovzdajte parametre servera MySQL a prihlasovacie údaje do databázy nasledovne, pričom DATABASE_USERNAME a DATABASE_PASSWORD nahraďte prihlasovacími údajmi vášho používateľa MySQL:
const Sequelize = require("sequelize");
const sequelize = new Sequelize(
'hello_world_db',
'DATABASE_USERNAME',
'DATABASE_PASSWORD',
{
host: 'DATABASE_HOST',
dialect: 'mysql'
}
);host je miesto, kde je hosťovaný server MySQL, takže budete musieť poskytnúť URL servera alebo IP adresu. Ak používate lokálne nainštalovaný server MySQL, môžete nahradiť DATABASE_HOST hodnotou localhost alebo 127.0.0.1.
Podobne, ak používate vzdialený server, uistite sa, že nahradíte hodnoty pripojenia k databáze príslušnými údajmi vzdialeného servera.
Poznámka: Ak používate akýkoľvek iný softvér databázového servera, môžete príslušne nahradiť parameter dialektu.
Ďalej zavolajte metódu authenticate() založenú na sľuboch na vytvorenie pripojenia k databáze aplikácie. Aby ste to urobili, pridajte nasledujúci blok kódu do súboru server.js:
...
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch((error) => {
console.error('Unable to connect to the database: ', error);
});Metóda authenticate() sa používa na pripojenie k databáze a kontroluje, či sú zadané prihlasovacie údaje správne. Tu je pripojenie k databáze predvolene otvorené a rovnaké pripojenie je možné použiť pre všetky dotazy. Kedykoľvek potrebujete pripojenie zavrieť, zavolajte metódu sequelize.close() po tomto volaní authenticate(). Ak sa chcete dozvedieť viac o Sequelize, pozrite si ich sprievodcu pre začínajúcich.
Väčšina metód poskytovaných Sequelize je asynchrónna. To znamená, že môžete spúšťať procesy vo vašej aplikácii, zatiaľ čo asynchrónny kódový blok je vo fáze vykonávania. Tiež, po úspešnom vykonaní asynchrónneho kódového bloku, vracia promise, čo je hodnota, ktorá sa vráti na konci procesu. Preto v asynchrónnych kódových blokoch môžete používať then(), catch() a finally() na vrátenie spracovaných dát.
V tomto bode bude súbor server.js vyzerať nasledovne:
const Sequelize = require("sequelize");
const sequelize = new Sequelize(
'hello_world_db',
'DATABASE_USERNAME',
'DATABASE_PASSWORD',
{
host: 'DATABASE_HOST',
dialect: 'mysql'
}
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch((error) => {
console.error('Unable to connect to the database: ', error);
});Uložte a zatvorte váš súbor.
V adresári projektu spustite aplikáciu server.js vykonaním nasledujúceho príkazu:
node server.jsVáš výstup bude vyzerať takto:
Connection has been established successfully!Databázové pripojenie ste úspešne vytvorili.
V tomto kroku ste nainštalovali Sequelize, vytvorili ukážkovú databázu a použili Sequelize na pripojenie k databáze. Ďalej budete pracovať s modelmi v Sequelize.
Vytváranie databázovej tabuľky pomocou Sequelize
Teraz, keď ste vytvorili ukážkovú databázu MySQL, môžete použiť Sequelize na vytvorenie tabuľky a jej naplnenie dátami. V Sequelize sa databázové tabuľky označujú ako modely. Model je abstrakcia, ktorá reprezentuje tabuľku v databáze. Modely definujú v Sequelize niekoľko vecí, ako napríklad názov tabuľky, detaily stĺpcov a dátové typy. V tomto kroku vytvoríte Sequelize model pre dáta kníh.
Na začiatok vytvorte nový súbor s názvom book.model.js v adresári projektu:
nano book.model.jsPodobne ako v predchádzajúcom kroku, pridajte kód Sequelize na inicializáciu databázy s novým importom DataTypes na začiatku súboru:
const { Sequelize, DataTypes } = require("sequelize");Sequelize obsahuje mnoho vstavaných typov údajov. Ak chcete získať prístup k týmto typom údajov, pridáte import pre DataTypes. Tento tutoriál sa odvoláva na niektoré často používané typy údajov, ako sú STRING, INTEGER a DATEONLY. Ak sa chcete dozvedieť viac o ďalších podporovaných typoch údajov, môžete sa odvolať na oficiálnu dokumentáciu Sequelize.
Potom zahrňte riadky, ktoré ste predtým použili na vytvorenie spojenia s databázou MySQL, pričom podľa potreby aktualizujte svoje prihlasovacie údaje MySQL:
...
const sequelize = new Sequelize(
'hello_world_db',
'DATABASE_USERNAME',
'DATABASE_PASSWORD',
{
host: 'DATABASE_HOST',
dialect: 'mysql'
}
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch((error) => {
console.error('Unable to connect to the database: ', error);
});Ďalej vytvoríte model s názvom books, ktorý zahŕňa title, author, release_date a ID subject. Na to použite metódu sequelize.define() ako je uvedené:
...
const Book = sequelize.define("books", {
title: {
type: DataTypes.STRING,
allowNull: false
},
author: {
type: DataTypes.STRING,
allowNull: false
},
release_date: {
type: DataTypes.DATEONLY,
},
subject: {
type: DataTypes.INTEGER,
}
});Metóda sequelize.define() definuje nový model, ktorý predstavuje tabuľku v databáze. Tento blok kódu vytvára tabuľku s názvom books a ukladá záznamy o knihách podľa title, author, release_date a subject.
V tomto kóde allowNull ukazuje, že hodnota stĺpca modelu nemôže byť null. Rovnako, ak potrebujete nastaviť takúto hodnotu, môžete použiť defaultValue: "value".
Ďalej pridáte model book do vašej databázy. Na to použijete metódu sync() nasledovne:
...
sequelize.sync().then(() => {
console.log('Book table created successfully!');
}).catch((error) => {
console.error('Unable to create table : ', error);
});V metóde sync() žiadate Sequelize, aby s databázou vykonal niekoľko úkonov. Pomocou tohto volania Sequelize automaticky vykoná SQL dotaz do databázy a vytvorí tabuľku a vypíše správu Tabuľka kníh bola úspešne vytvorená!.
Ako bolo spomenuté, metóda sync() je metóda založená na prísľube (promise), čo znamená, že môže tiež vykonávať spracovanie chýb. V tomto bloku kódu skontrolujete, či bola tabuľka úspešne vytvorená. Ak nie, vráti chybu cez metódu catch a vypíše ju na výstup.
Poznámka: Synchronizáciu modelu môžete spravovať odoslaním parametrov force, aby sa vynútila tvorba novej tabuľky, ak neexistuje, alebo použiť existujúcu. Tu je niekoľko príkladov, ktoré vám môžu byť užitočné pri práci so Sequelize:
model.sync(): Toto vytvorí tabuľku, ak ešte neexistuje.model.sync({ force: true }): Tento príkaz vytvorí tabuľku tým, že ju najprv zmaže, ak už rovnaká tabuľka existuje.
Konečný kód bude vyzerať takto:
const {Sequelize, DataTypes} = require("sequelize");
const sequelize = new Sequelize(
'hello_world_db',
'DATABASE_USERNAME',
'DATABASE_PASSWORD',
{
host: 'DATABASE_HOST',
dialect: 'mysql'
}
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch((error) => {
console.error('Unable to connect to the database: ', error);
});
const Book = sequelize.define("books", {
title: {
type: DataTypes.STRING,
allowNull: false
},
author: {
type: DataTypes.STRING,
allowNull: false
},
release_date: {
type: DataTypes.DATEONLY,
},
subject: {
type: DataTypes.INTEGER,
}
});
sequelize.sync().then(() => {
console.log('Book table created successfully!');
}).catch((error) => {
console.error('Unable to create table : ', error);
});Uložte a zatvorte váš súbor.
Spustite svoju aplikáciu pomocou nasledujúceho príkazu:
node book.model.jsV príkazovom riadku dostanete nasledujúci výstup:
Executing (default): SELECT 1+1 AS result
Executing (default): CREATE TABLE IF NOT EXISTS `books` (`id` INTEGER NOT NULL auto_increment , `title` VARCHAR(255) NOT NULL, `author` VARCHAR(255) NOT NULL, `release_date` DATE, `subject` INTEGER, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
Connection has been established successfully.
Executing (default): SHOW INDEX FROM `books`
Book table created successfully!Vo výstupe uvidíte, že návratový záznam obsahuje správu, Stôl kníh bol úspešne vytvorený!. Môžete to overiť kontrolou svojej databázy, kde sa vytvorila nová tabuľka books v databáze hello_world_db.
Ak chcete overiť vytvorenie novej tabuľky, prihláste sa do svojho inštancie MySQL:
mysql -u YOUR_USERNAME -pPo zadaní svojho hesla prepnite do ukážkovej databázy:
USE hello_world_db;A potom spustite príkaz na zobrazenie tabuliek:
SHOW TABLES;Váš výstup bude podobný tomuto:
+---------------------------+
| Tables_in_hello_world_db |
+---------------------------+
| books |
+---------------------------+
1 row in set (0.00 sec)Nakoniec sa odpojte od servera MySQL:
mysql> QUITOverili ste, že vytvorenie modelu book bolo úspešné. Pomocou tohto postupu môžete vytvoriť ľubovoľný počet modelov postupovaním rovnakým spôsobom.
V tomto kroku ste vytvorili model v databáze a začali ste pracovať s modelom pomocou vstavaných metód. Tiež ste použili typy údajov podporované Sequelize na definovanie svojho modelu. Ďalej budete pracovať so základnými dotazmi modelu.
Používanie Sequelize pre dotazy do databázy
V tomto kroku budete používať vstavané dotazy Sequelize na vkladanie, výber, výber s podmienkami a mazanie.
Vkladanie nového záznamu
V predchádzajúcom kroku ste vytvorili model book v databáze. V tejto časti do tohto modelu vložíte údaje.
Na začiatok skopírujte obsah súboru book.model.js z predchádzajúceho kroku. Vytvorte nový súbor s názvom book.controller.js, ktorý bude spracovávať logiku dotazov. Pridajte kód zo súboru book.model.js do book.controller.js.
V súbore book.controller.js nájdite metódu sync(). V metóde sync() pridajte nasledujúce zvýraznené riadky:
...
sequelize.sync().then(() => {
console.log('Book table created successfully!');
Book.create({
title: "Clean Code",
author: "Robert Cecil Martin",
release_date: "2021-12-14",
subject: 3
}).then(res => {
console.log(res)
}).catch((error) => {
console.error('Failed to create a new record : ', error);
});
}).catch((error) => {
console.error('Unable to create table : ', error);
});Tu vložíte nový záznam knihy do modelu books, ktorý ste už vytvorili, pomocou metódy sync(), ktorá podporuje pridávanie nových záznamov do predtým vytvorených modelov. Keď sa metóda sync() úspešne vykoná, spustí sa metóda then(). Vo vnútri metódy then() zavoláte metódu create(), aby ste vložili nové záznamy do modelu.
Na pridanie údajov do databázy ako objekt použijete metódu create(). Zvýraznená časť kódu vloží nový záznam do existujúcej tabuľky books. V tomto príklade pridávate Clean Code od Roberta Cecila Martina, ktorý bol zaradený do kategórie s subject ID 3. Rovnaký kód môžete použiť, aktualizovaný o informácie pre iné knihy, na pridanie nových záznamov do vašej databázy.
Uložte a zatvorte súbor.
Spustite aplikáciu pomocou nasledujúceho príkazu:
node book.controller.jsVáš výstup bude vyzerať podobne ako nasledujúce:
books {
dataValues:
{ id: 1,
title: 'Clean Code',
author: 'Robert Cecil Martin',
release_date: '2021-12-14',
subject: 3,
updatedAt: 2021-12-14T10:12:16.644Z,
...
}Do modelu, ktorý ste vytvorili v databáze, ste vložili nový záznam. Môžete pokračovať v pridávaní viacerých záznamov pomocou rovnakého postupu.
Výber všetkých záznamov
V tejto sekcii vyberiete a získate všetky záznamy o knihách z databázy pomocou metódy findAll(). Na to najskôr otvorte book.controller.js a odstráňte predchádzajúcu metódu Book.create(). V metóde sync() pridajte metódu Book.findAll() nasledovne:
...
sequelize.sync().then(() => {
Book.findAll().then(res => {
console.log(res)
}).catch((error) => {
console.error('Failed to retrieve data : ', error);
});
}).catch((error) => {
console.error('Unable to create table : ', error);
});
...Uložte a zatvorte súbor.
Ďalej spustite aplikáciu znova pomocou nasledujúceho príkazu:
node book.controller.jsVáš výstup bude vyzerať podobne ako nasledujúce:
[
books {
dataValues: {
id: 1,
title: 'Clean Code',
author: 'Robert Cecil Martin',
release_date: '2020-01-01',
subject: 3,
createdAt: 2021-02-22T09:13:55.000Z,
updatedAt: 2021-02-22T09:13:55.000Z
},
_previousDataValues: {
id: 1,
title: 'Clean Code',
author: 'Robert Cecil Martin',
release_date: '2020-01-01',
subject: 3,
createdAt: 2021-02-22T09:13:55.000Z,
updatedAt: 2021-02-22T09:13:55.000Z
},
...
]Výstup obsahuje všetky údaje o knihách ako objekt poľa. Úspešne ste použili metódu Sequelize findAll() na vrátenie všetkých údajov o knihách z databázy.
Výber s použitím klauzuly where
V tejto časti budete vyberať hodnoty s podmienkami pomocou klauzuly where. Klauzula where sa používa na určenie podmienky pri získavaní údajov. V tomto návode získate knihu podľa konkrétneho ID záznamu z databázy pomocou metódy findOne().
Na to otvorte book.controller.js na úpravu, odstráňte metódu findAll() a pridajte nasledujúce riadky:
...
sequelize.sync().then(() => {
Book.findOne({
where: {
id: 1
}
}).then(res => {
console.log(res)
}).catch((error) => {
console.error('Failed to retrieve data : ', error);
});
}).catch((error) => {
console.error('Unable to create table : ', error);
});Tu vyberiete konkrétny záznam knihy z databázy pomocou metódy findOne() s možnosťou where. V tomto príklade získavate údaje o knihe, ktorej id je rovné 1.
Uložte a zatvorte súbor.
Ďalej spustite aplikáciu:
node book.controller.jsVáš výstup bude vyzerať podobne ako nasledujúce:
books {
dataValues: {
id: 1,
title: 'Clean Code',
author: 'Robert Cecil Martin',
release_date: '2020-01-01',
subject: 'Science',
createdAt: 2021-02-22T09:13:55.000Z,
updatedAt: 2021-02-22T09:13:55.000Z
},
...
}Úspešne ste použili klauzuly where na získanie dát z modelov Sequelize. Klauzulu where môžete použiť v databázovej aplikácii na zachytenie podmienených dát.
Odstraňovanie záznamu
Ak chcete odstrániť konkrétny záznam z databázového modelu, použite metódu destroy() s možnosťou where. Na to otvorte book.controller.js, odstráňte metódu findOne() a pridajte nasledujúce zvýraznené riadky:
...
sequelize.sync().then(() => {
Book.destroy({
where: {
id: 2
}
}).then(() => {
console.log("Successfully deleted record.")
}).catch((error) => {
console.error('Failed to delete record : ', error);
});
}).catch((error) => {
console.error('Unable to create table : ', error);
});Tu odstránite záznam knihy z databázy použitím metódy destroy() s možnosťou where a odovzdaním id knihy, ktorú chcete odstrániť. Odstránite záznam knihy, ktorého id sa rovná 2.
Uložte a zatvorte súbor.
Ďalej spustite aplikáciu:
node book.controller.jsVáš výstup bude vyzerať nasledovne:
Successfully deleted record.Záznam bol odstránený.
V tomto kroku ste experimentovali so svojím databázovým modelom a dotazovaním na modely. Inicializovali ste databázu, vytvorili modely, vložili záznamy, načítali záznamy, načítali záznamy s podmienkami pomocou klauzuly where a vymazali vybrané záznamy. S týmito znalosťami Sequelize teraz vytvoríte asociácie v Sequelize. Následne budete schopní definovať a pracovať s rôznymi vzťahmi pomocou modelov Sequelize.
Vytváranie asociácií pomocou Sequelize
V tomto kroku použijete štandardné typy asociácií, ktoré Sequelize podporuje: jeden-na-jedného, jeden-na-viacerých a viacerí-na-viacerých asociácie. Budete používať ukážkové údaje o študentoch, kurzoch a úrovniach známok.
Sequelize používa typy asociácií založené na nasledujúcich databázových vzťahoch:
vzťah jeden ku jednému: Vzťah jeden ku jednému znamená, že záznam v jednej tabuľke je spojený presne s jedným záznamom v inej tabuľke. V termínoch Sequelize môžete použiť asociácie
belongsTo()ahasOne()na vytvorenie tohto typu vzťahu.jeden k mnohým vzťah: Vzťah jeden k mnohým znamená, že jeden záznam v jednej tabuľke je prepojený s viacerými záznamami v inej tabuľke. So Sequelize môžete použiť metódy asociácií
hasMany()na vytvorenie tohto typu vzťahu.many-to-many vzťah: Many-to-many vzťah znamená, že viacero záznamov v jednej tabuľke je spojených s viacerými záznamami v inej tabuľke. Pomocou Sequelize môžete použiť
belongsToMany()asociácie na vytvorenie tohto typu vzťahu.
Pred vytvorením týchto asociácií najskôr vytvoríte novú databázu s názvom student_db a pridáte nové modely a niektoré ukážkové údaje pre študentov, kurzy a úroveň známok.
Na vytvorenie databázy postupujte podľa rovnakého postupu v časti Inštalácia a konfigurácia Sequelize na prihlásenie do MySQL a vytvorenie databázy s názvom student_db. Po vytvorení novej databázy sa odhláste z MySQL. Ďalej začnete vytvárať vzťahy v databáze.
Vytváranie vzťahu jeden ku jednému s belongsTo()
V tejto časti vytvoríte vzťah jeden ku jednému pomocou modelov Sequelize. Predstavte si, že chcete získať údaje jedného študenta spolu s jeho úrovňou triedy. Keďže jeden študent môže mať len jednu úroveň triedy, tento typ asociácie je vzťah jeden ku jednému a môžete použiť metódu belongsTo().
Poznámka: Existuje rozdiel medzi belongsTo() a hasOne(). belongsTo() pridá foreignKey do zdrojovej tabuľky, zatiaľ čo hasOne() ho pridá do cieľovej tabuľky. V každom prípade, ak sa obe vzťahy používajú súčasne, bude to fungovať ako obojstranné jeden-na-jeden vzťahy v Sequelize.
Metóda belongsTo() vám umožňuje vytvoriť vzťah typu jeden ku jednému medzi dvoma modelmi Sequelize. V tomto príklade používate modely Student a Grade.
Vytvorte nový súbor s názvom one_to_one.js. Rovnako ako v predchádzajúcej časti, Pripojenie k databáze MySQL, zahrňte riadky na vytvorenie pripojenia k databáze a autentifikáciu používateľa MySQL na začiatok súboru. Nezabudnite aktualizovať prihlasovacie údaje MySQL podľa potreby:
const { Sequelize, DataTypes } = require("sequelize");
const sequelize = new Sequelize(
'student_db',
'DATABASE_USERNAME',
'DATABASE_PASSWORD',
{
host: 'DATABASE_HOST',
dialect: 'mysql'
}
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch((error) => {
console.error('Unable to connect to the database: ', error);
});V tejto časti vytvoríte tri modely v novej databáze student_db: Student, Grade a Course. Začnete vytvorením modelov Student a Grade. Neskôr v tomto kroku vytvoríte model Courses.
Pre model Student pridajte nasledujúci blok kódu do one_to_one.js:
...
const Student = sequelize.define("students", {
student_id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false
}
});Tento študentský model obsahuje dva stĺpce: student_id a name.
Ako ďalšie pridajte kódový blok pre model Grade:
...
const Grade = sequelize.define("grades", {
grade: {
type: DataTypes.INTEGER,
allowNull: false
}
});Model Grade obsahuje stĺpec grade.
Na demonštráciu asociácií budete musieť pridať do databázy ukážkové údaje. Na to použijete metódu bulk(). Namiesto vkladania údajov riadok po riadku, metóda bulkCreate() vám umožní vložiť viacero riadkov do vašich databázových modelov naraz.
Takže teraz naimportujte dáta Grade a Student do príslušných modelov v databáze, ako je uvedené:
...
const grade_data = [{grade : 9}, {grade : 10}, {grade : 11}]
const student_data = [
{name : "John Baker", gradeId: 2},
{name : "Max Butler", gradeId: 1},
{name : "Ryan Fisher", gradeId: 3},
{name : "Robert Gray", gradeId: 2},
{name : "Sam Lewis", gradeId: 1}
]
sequelize.sync({ force: true }).then(() => {
Grade.bulkCreate(grade_data, { validate: true }).then(() => {
Student.bulkCreate(student_data, { validate: true }).then(() => {
…
}).catch((err) => { console.log(err); });
}).catch((err) => { console.log(err); });
}).catch((error) => {
console.error('Unable to create the table : ', error);
});Tu zadáte ukážkové údaje a vložíte ich do modelov Student a Grade. S vašou databázou, modelmi a ukážkovými údajmi pripravenými, ste pripravení vytvárať asociácie.
V súbore one-to-one.js pridajte nasledujúci riadok pod blok student_data:
...
Student.belongsTo(Grade);Ďalej budete musieť skontrolovať, či asociácia funguje správne. Aby ste to urobili, môžete získať všetky údaje o študentoch spolu s priradenými triedami tak, že do metódy findAll() vložíte parameter include.
Keďže potrebujete získať úroveň študenta, ako model použijete Grade. V metóde sequelize.sync() pridajte zvýraznené riadky nasledovne:
...
sequelize.sync({ force: true }).then(() => {
Grade.bulkCreate(grade_data, { validate: true }).then(() => {
Student.bulkCreate(student_data, { validate: true }).then(() => {
Student.findAll({
include: [{
model: Grade
}]
}).then(result => {
console.log(result)
}).catch((error) => {
console.error('Failed to retrieve data : ', error);
});
}).catch((err) => { console.log(err); });
}).catch((err) => { console.log(err); });
}).catch((error) => {
console.error('Unable to create the table : ', error);
});Kompletný kód vyzerá nasledovne:
const {Sequelize, DataTypes} = require("sequelize");
const sequelize = new Sequelize(
'student_db',
'DATABASE_USERNAME',
'DATABASE_PASSWORD',
{
host: 'DATABASE_HOST',
dialect: 'mysql'
}
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch((error) => {
console.error('Unable to connect to the database: ', error);
});
const Student = sequelize.define("students", {
student_id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false
}
});
const Grade = sequelize.define("grades", {
grade: {
type: DataTypes.INTEGER,
allowNull: false
}
});
const grade_data = [{grade : 9}, {grade : 10}, {grade : 11}]
const student_data = [
{name : "John Baker", gradeId: 2},
{name : "Max Butler", gradeId: 1},
{name : "Ryan Fisher", gradeId: 3},
{name : "Robert Gray", gradeId: 2},
{name : "Sam Lewis", gradeId: 1}
]
// One-To-One association
Student.belongsTo(Grade);
sequelize.sync({ force: true }).then(() => {
Grade.bulkCreate(grade_data, { validate: true }).then(() => {
Student.bulkCreate(student_data, { validate: true }).then(() => {
Student.findAll({
include: [{
model: Grade
}]
}).then(result => {
console.log(result)
}).catch((error) => {
console.error('Failed to retrieve data : ', error);
});
}).catch((err) => { console.log(err); });
}).catch((err) => { console.log(err); });
}).catch((error) => {
console.error('Unable to create the table : ', error);
});Uložte a zatvorte váš súbor.
Spustite súbor pomocou nasledujúceho príkazu:
node one_to_one.jsVýstup bude dlhý a uvidíte údaje všetkých študentov s úrovňou známok. Tu je úryvok výstupu zobrazujúci údaje študentov:
students {
dataValues:
{ student_id: '3e786a8f-7f27-4c59-8e9c-a8c606892288',
name: 'Sam Lewis',
createdAt: 2021-12-16T08:49:38.000Z,
updatedAt: 2021-12-16T08:49:38.000Z,
gradeId: 1,
grade: [grades] },
_previousDataValues:
...V závislosti od toho, aké nástroje príkazového riadku používate, môže byť výstup zobrazený ako rozšírený pohľad alebo nie. Ak ide o rozšírený pohľad, výstupom sa zobrazí rozšírený objekt grade.
V tejto časti ste vytvorili vzťah jeden k jednému pomocou volania metódy Student.belongsTo(Grade); a získali ste podrobnosti podľa vytvorenej asociácie.
Vytvorenie vzťahu jeden-ku-viacerým pomocou hasMany()
V tejto sekcii vytvoríte vzťah jeden-ku-viacerým pomocou modelov Sequelize. Predstavte si, že chcete získať všetkých študentov spojených s vybranou úrovňou triedy. Keďže jedna konkrétna úroveň triedy môže mať viacero študentov, ide o vzťah jeden-ku-viacerým.
Na začiatok skopírujte obsah súboru one_to_one.js do nového súboru s názvom one_to_many.js. V súbore one_to_many.js odstráňte riadky za blokom student_data. Váš súbor one_to_many.js bude vyzerať takto:
const {Sequelize, DataTypes} = require("sequelize");
const sequelize = new Sequelize(
'student_db',
'DATABASE_USERNAME',
'DATABASE_PASSWORD',
{
host: 'DATABASE_HOST',
dialect: 'mysql'
}
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch((error) => {
console.error('Unable to connect to the database: ', error);
});
const Student = sequelize.define("students", {
student_id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false
}
});
const Grade = sequelize.define("grades", {
grade: {
type: DataTypes.INTEGER,
allowNull: false
}
});
const grade_data = [ {grade : 9}, {grade : 10}, {grade : 11}]
const student_data = [
{name : "John Baker", gradeId: 2},
{name : "Max Butler", gradeId: 1},
{name : "Ryan Fisher", gradeId: 3},
{name : "Robert Gray", gradeId: 2},
{name : "Sam Lewis", gradeId: 1}
]Po bloku student_data použite metódu hasMany() na vytvorenie nového vzťahu:
...
Grade.hasMany(Student)Metóda hasMany() vám umožňuje vytvoriť vzťah jeden-k-mnohým medzi dvoma modelmi Sequelize. Tu používate modely Grade a Student.
Ďalej pridajte metódu sequelize.sync() spolu s metódou findAll() pod riadok hasMany():
...
sequelize.sync({ force: true }).then(() => {
Grade.bulkCreate(grade_data, { validate: true }).then(() => {
Student.bulkCreate(student_data, { validate: true }).then(() => {
Grade.findAll({
where: {
grade: 9
},
include: [{
model: Student
}]
}).then(result => {
console.dir(result, { depth: 5 });
}).catch((error) => {
console.error('Failed to retrieve data : ', error);
});
}).catch((err) => { console.log(err); });
}).catch((err) => { console.log(err); });
}).catch((error) => {
console.error('Unable to create table : ', error);
});Tu sa pokúšate získať všetkých študentov v konkrétnom ročníku – v tomto prípade všetkých študentov v 9. ročníku 9. Tiež ste pridali model Student do možnosti include.
Tu je kompletný kód:
const {Sequelize, DataTypes} = require("sequelize");
const sequelize = new Sequelize(
'student_db',
'DATABASE_USERNAME',
'DATABASE_PASSWORD',
{
host: 'DATABASE_HOST',
dialect: 'mysql'
}
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch((error) => {
console.error('Unable to connect to the database: ', error);
});
const Student = sequelize.define("students", {
student_id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false
}
});
const Grade = sequelize.define("grades", {
grade: {
type: DataTypes.INTEGER,
allowNull: false
}
});
const grade_data = [ {grade : 9}, {grade : 10}, {grade : 11}]
const student_data = [
{name : "John Baker", gradeId: 2},
{name : "Max Butler", gradeId: 1},
{name : "Ryan Fisher", gradeId: 3},
{name : "Robert Gray", gradeId: 2},
{name : "Sam Lewis", gradeId: 1}
]
// One-To-Many relationship
Grade.hasMany(Student);
sequelize.sync({ force: true }).then(() => {
Grade.bulkCreate(grade_data, { validate: true }).then(() => {
Student.bulkCreate(student_data, { validate: true }).then(() => {
Grade.findAll({
where: {
grade: 9
},
include: [{
model: Student
}]
}).then(result => {
console.dir(result, { depth: 5 });
}).catch((error) => {
console.error('Failed to retrieve data : ', error);
});
}).catch((err) => { console.log(err); });
}).catch((err) => { console.log(err); });
}).catch((error) => {
console.error('Unable to create table : ', error);
});Uložte a zatvorte váš súbor.
Spustite súbor pomocou nasledujúceho príkazu:
node one_to_many.jsVýstup bude vyzerať podobne ako nasledujúce. Bude dosť dlhý, ale všetci študenti v 9. ročníku budú vrátení nasledovne:
[ grades {
dataValues:
{ id: 1,
grade: 9,
createdAt: 2021-12-20T05:12:31.000Z,
updatedAt: 2021-12-20T05:12:31.000Z,
students:
[ students {
dataValues:
{ student_id: '8a648756-4e22-4bc0-8227-f590335f9965',
name: 'Sam Lewis',
createdAt: 2021-12-20T05:12:31.000Z,
updatedAt: 2021-12-20T05:12:31.000Z,
gradeId: 1 },
...
students {
dataValues:
{ student_id: 'f0304585-91e5-4efc-bdca-501b3dc77ee5',
name: 'Max Butler',
createdAt: 2021-12-20T05:12:31.000Z,
updatedAt: 2021-12-20T05:12:31.000Z,
gradeId: 1 },
...V tejto časti ste vytvorili vzťah jeden k mnohým pomocou volania metódy Grade.hasMany(Student);. Vo výstupe ste získali podrobnosti podľa vytvoreného asociácie.
Vytváranie vzťahov mnoho-ku-mnohým pomocou belongsToMany()
V tejto časti vytvoríte vzťahy mnohí-ku-mnohým pomocou modelov Sequelize. Ako príklad si predstavte situáciu, kde sú študenti zapísaní na kurzy. Jeden študent sa môže zapísať do viacerých kurzov a jeden kurz môže mať viacerých študentov. Toto je vzťah mnohí-ku-mnohým. Na jeho implementáciu pomocou Sequelize použijete modely Student, Course a StudentCourse s metódou belongsToMany().
Na začiatok vytvorte súbor s názvom many_to_many.js a pridajte bloky kódu pre inicializáciu a autentifikáciu databázy nasledovne. (Môžete použiť bloky kódu z predchádzajúceho príkladu one_to_many.js.) Nezabudnite aktualizovať zvýraznené hodnoty pripojenia k databáze podľa potreby.
const {Sequelize, DataTypes} = require("sequelize");
const sequelize = new Sequelize(
'student_db',
'DATABASE_USERNAME',
'DATABASE_PASSWORD',
{
host: 'DATABASE_HOST',
dialect: 'mysql'
}
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch((error) => {
console.error('Unable to connect to the database: ', error);
});Ďalej vytvoríte databázové modely pre vzťahy mnoho k mnohým: Student a Course. Potom pridáte do týchto modelov niekoľko ukážkových údajov.
...
const Student = sequelize.define("students", {
student_id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
},
name: {
type: DataTypes.STRING,
allowNull: false
}
});
const Course = sequelize.define("courses", {
course_name: {
type: DataTypes.STRING,
allowNull: false
}
});
const StudentCourse = sequelize.define('StudentCourse', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false
}
});
const course_data = [
{course_name : "Science"},
{course_name : "Maths"},
{course_name : "History"}
]
const student_data = [
{name : "John Baker", courseId: 2},
{name : "Max Butler", courseId: 1},
{name : "Ryan Fisher", courseId: 3},
{name : "Robert Gray", courseId: 2},
{name : "Sam Lewis", courseId: 1}
]
const student_course_data = [
{studentId : 1, courseId: 1},
{studentId : 2, courseId: 1},
{studentId : 2, courseId: 3},
{studentId : 3, courseId: 2},
{studentId : 1, courseId: 2},
]Tu vytvoríte modely Student a Course a poskytnete niektoré ukážkové dáta. Tiež nastavíte courseID, ktorý použijete na získanie študentov podľa tohto typu vzťahu.
Nakoniec ste definovali nový model s názvom StudentCourse, ktorý spravuje údaje o vzťahoch medzi Student a Course. V tomto príklade je studentId 1 zapísaný na courseId 1 a courseId 2.
Dokončili ste inicializáciu databázy a pridali vzorové dáta do databázy. Ďalej vytvorte vzťahy mnoho k mnohým pomocou metódy belongsToMany() takto:
...
Course.belongsToMany(Student, { through: 'StudentCourse'})
Student.belongsToMany(Course, { through: 'StudentCourse'})V rámci metódy belongsToMany() odovzdáte konfiguráciu through s názvom modelu ako konfiguračnú možnosť. V tomto prípade je to StudentCourse. Toto je tabuľka, ktorá spravuje vzťahy mnoho k mnohým.
Nakoniec môžete skontrolovať, či asociácia funguje správne, tak že získate všetky údaje o kurzoch spolu s priradenými študentmi. Urobíte to tak, že odovzdáte parameter include do metódy findAll(). Pridajte nasledujúce riadky do súboru many_to_many.js:
...
sequelize.sync({ force: true }).then(() => {
Course.bulkCreate(course_data, { validate: true }).then(() => {
Student.bulkCreate(student_data, { validate: true }).then(() => {
StudentCourse.bulkCreate(student_course_data, { validate: true }).then(() => {
Course.findAll({
include: {
model: Student,
},
}).then(result => {
console.log(result);
}).catch((error) => {
console.error('Failed to retrieve data : ', error);
});
}).catch((error) => {
console.log(error);
});
}).catch((error) => {
console.log(error);
});
}).catch((error) => {
console.log(error);
});
}).catch((error) => {
console.error('Unable to create table : ', error);
});Kompletný kód vyzerá nasledovne:
const {Sequelize, DataTypes} = require("sequelize");
const sequelize = new Sequelize(
'student_db',
'DATABASE_USERNAME',
'DATABASE_PASSWORD',
{
host: 'DATABASE_HOST',
dialect: 'mysql'
}
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch((error) => {
console.error('Unable to connect to the database: ', error);
});
const Student = sequelize.define("students", {
student_id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
},
name: {
type: DataTypes.STRING,
allowNull: false
}
});
const Course = sequelize.define("courses", {
course_name: {
type: DataTypes.STRING,
allowNull: false
}
});
const StudentCourse = sequelize.define('StudentCourse', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false
}
});
const course_data = [
{course_name : "Science"},
{course_name : "Maths"},
{course_name : "History"}
]
const student_data = [
{name : "John Baker", courseId: 2},
{name : "Max Butler", courseId: 1},
{name : "Ryan Fisher", courseId: 3},
{name : "Robert Gray", courseId: 2},
{name : "Sam Lewis", courseId: 1}
]
const student_course_data = [
{studentId : 1, courseId: 1},
{studentId : 2, courseId: 1},
{studentId : 2, courseId: 3},
{studentId : 3, courseId: 2},
{studentId : 1, courseId: 2},
]
Course.belongsToMany(Student, { through: 'StudentCourse'})
Student.belongsToMany(Course, { through: 'StudentCourse'})
sequelize.sync({ force: true }).then(() => {
Course.bulkCreate(course_data, { validate: true }).then(() => {
Student.bulkCreate(student_data, { validate: true }).then(() => {
StudentCourse.bulkCreate(student_course_data, { validate: true }).then(() => {
Course.findAll({
include: {
model: Student,
},
}).then(result => {
console.log(result);
}).catch((error) => {
console.error('Failed to retrieve data : ', error);
});
}).catch((error) => {
console.log(error);
});
}).catch((error) => {
console.log(error);
});
}).catch((error) => {
console.log(error);
});
}).catch((error) => {
console.error('Unable to create table : ', error);
});Uložte a zatvorte súbor.
Spustite súbor pomocou nasledujúceho príkazu:
node many_to_many.jsVýstup bude dlhý, ale bude vyzerať niečo podobné ako nasledujúce:
[ courses {
dataValues:
{ id: 1,
course_name: 'Science',
createdAt: 2022-05-11T04:27:37.000Z,
updatedAt: 2022-05-11T04:27:37.000Z,
students: [Array] },
_previousDataValues:
{ id: 1,
course_name: 'Science',
createdAt: 2022-05-11T04:27:37.000Z,
updatedAt: 2022-05-11T04:27:37.000Z,
students: [Array] },
_changed: Set {},
_options:
{ isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
include: [Array],
includeNames: [Array],
includeMap: [Object],
includeValidated: true,
attributes: [Array],
raw: true },
isNewRecord: false,
students: [ [students], [students] ] },
courses {
dataValues:
{ id: 2,
course_name: 'Maths',
createdAt: 2022-05-11T04:27:37.000Z,
updatedAt: 2022-05-11T04:27:37.000Z,
students: [Array] },
_previousDataValues:
...Ako môžete vidieť v tomto výstupe, boli získané kurzy s priradenými študentmi. V bloku courses uvidíte samostatné hodnoty id, ktoré označujú každý kurz. Napríklad id: 1 je priradené k course_name: Science pre triedu Science, zatiaľ čo id: 2 je trieda Maths, a tak ďalej.
V databáze môžete vidieť tri vytvorené tabuľky s ukážkovými údajmi, ktoré ste vložili.
V tomto kroku ste použili Sequelize na vytvorenie vzťahov jeden-ku-jednému, jeden-ku-viacerým a mnohí-ku-viacerým. Ďalej budete pracovať s neformálnymi dotazmi.
Práca s neformátovanými dotazmi
V tomto kroku budete pracovať s nespracovanými dotazmi v Sequelize. V predchádzajúcich krokoch ste používali vstavané metódy Sequelize, ako napríklad insert() a findAll(), na vkladanie a výber údajov z databázy. Možno ste si všimli, že tieto metódy sa riadia konkrétnym vzorom pri písaní dotazu. Avšak pri používaní nespracovaných dotazov sa nemusíte zaoberať vstavanými metódami Sequelize a vzormi. Využitím svojich znalostí SQL dotazov môžete v Sequelize vykonávať rôzne dotazy, od jednoduchých po pokročilejšie.
Tu je príklad surových dotazov, ktoré vykonávajú akciu výberu všetkých hodnôt z konkrétnej tabuľky, mazania vybraných hodnôt podľa podmienky a aktualizácie tabuľky s danými hodnotami.
SELECT * FROM table_name;
DELETE FROM table_name WHERE condition;
UPDATE table_name SET y = 42 WHERE x = 12;V Sequelize je možné používať nezpracované dotazy predovšetkým dvoma spôsobmi: nahradením v poli a nahradením v objekte. Keď odovzdávate hodnoty do SQL dotazu, môžete použiť buď pole, alebo objekt na vykonanie tohto nahradenia.
Pred napísaním surového dopytu budete najprv musieť poskytnúť údaje študentov v ukážkovej databáze. Nasledujúc predchádzajúcu časť, Vytvorenie ukážkovej databázy, prihláste sa do MySQL, vytvorte databázu s názvom sample_student_db a odhláste sa z MySQL.
Ďalej pridáte nejaké surové dáta, aby ste mohli začať pracovať so surovými dotazmi. Vytvorte nový súbor s názvom add_student_records.js a pridajte nasledujúce bloky kódu, ktoré obsahujú predtým diskutované metódy Sequelize authenticate(), sync() a bulkCreate().
const {Sequelize, DataTypes} = require("sequelize");
const sequelize = new Sequelize(
'sample_student_db',
'DATABASE_USERNAME',
'DATABASE_PASSWORD',
{
host: 'DATABASE_HOST',
dialect: 'mysql'
}
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch((error) => {
console.error('Unable to connect to the database: ', error);
});
const Student = sequelize.define("students", {
student_id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false
}
});
const student_data = [
{name : "John Baker"},
{name : "Max Butler"},
{name : "Ryan Fisher"},
{name : "Robert Gray"},
{name : "Sam Lewis"}
]
sequelize.sync({ force: true }).then(() => {
Student.bulkCreate(student_data, { validate: true }).then((result) => {
console.log(result);
}).catch((error) => {
console.log(error);
});
}).catch((error) => {
console.error('Unable to create table : ', error);
});Tu inicializujete pripojenie k databáze, vytvoríte model a vložíte niekoľko záznamov študentov do novej databázy.
Uložte a zatvorte súbor.
Ďalej spustite tento skript pomocou nasledujúceho príkazu:
node add_student_records.jsVýstup bude niečo podobné nasledujúcemu. Bude to dosť dlhé, ale všetky záznamy študentov, ktoré ste vložili, budú vrátené takto. Vezmite na vedomie, že keďže student_id je automaticky generovaná hodnota UUID (Univerzálne jedinečné identifikátory), bude sa líšiť v závislosti od používateľa.
Executing (default): SELECT 1+1 AS result
Executing (default): DROP TABLE IF EXISTS `students`;
Connection has been established successfully.
Executing (default): DROP TABLE IF EXISTS `students`;
Executing (default): CREATE TABLE IF NOT EXISTS `students` (`student_id` CHAR(36) BINARY , `name` VARCHAR(255) NOT NULL, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`student_id`)) ENGINE=InnoDB;
Executing (default): SHOW INDEX FROM `students`
Executing (default): INSERT INTO `students` (`student_id`,`name`,`createdAt`,`updatedAt`) VALUES ('45d1f26c-ba76-431f-ac5f-f41282351710','John Baker','2022-06-03 07:27:49','2022-06-03 07:27:49'),('1cb4e34d-bfcf-4a97-9624-e400b9a1a5f2','Max Butler','2022-06-03 07:27:49','2022-06-03 07:27:49'),('954c576b-ba1c-4dbc-a5c6-8eaf22bbbb04','Ryan Fisher','2022-06-03 07:27:49','2022-06-03 07:27:49'),('e0f15cd3-0025-4032-bfe8-774e38e14c5f','Robert Gray','2022-06-03 07:27:49','2022-06-03 07:27:49'),('826a0ec9-edd0-443f-bb12-068235806659','Sam Lewis','2022-06-03 07:27:49','2022-06-03 07:27:49');
[
students {
dataValues: {
student_id: '45d1f26c-ba76-431f-ac5f-f41282351710',
name: 'John Baker',
createdAt: 2022-06-03T07:27:49.453Z,
updatedAt: 2022-06-03T07:27:49.453Z
},
_previousDataValues: {
name: 'John Baker',
student_id: '45d1f26c-ba76-431f-ac5f-f41282351710',
createdAt: 2022-06-03T07:27:49.453Z,
updatedAt: 2022-06-03T07:27:49.453Z
},
…V nasledujúcej časti budete používať surové dotazy pomocou jedného z výstupov student_id v kóde vyššie. Skopírujte si ho, aby ste ho mali pre nasledujúce časti, kde budete používať metódu query() na nahradenie polí a objektov.
Nahradenie poľa
V tejto sekcii použijete metódu query() na nahradenie poľa. S touto metódou môže Sequelize vykonávať surové SQL dotazy alebo už pripravené SQL dotazy.
Na začiatok skopírujte obsah súboru server.js z kroku 1, pretože ten obsahuje metódu Sequelize() na inicializáciu aj inicializáciu databázy. Vložte obsah do nového súboru s názvom array_raw_query.js. Aktualizujte názov databázy na sample_student_db:
const {Sequelize, DataTypes} = require("sequelize");
const sequelize = new Sequelize(
'sample_student_db',
'DATABASE_USERNAME',
'DATABASE_PASSWORD',
{
host: 'DATABASE_HOST',
dialect: 'mysql'
}
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch((error) => {
console.error('Unable to connect to the database: ', error);
});Na konci súboru pridajte nasledujúci blok kódu na nahradenie poľa, pričom sa uistite, že REPLACE_STUDENT_ID nahradíte hodnotou student_id, ktorú ste skopírovali v predchádzajúcej časti.
...
sequelize.query(
'SELECT * FROM students WHERE student_id = ?',
{
replacements: ['REPLACE_STUDENT_ID'],
type: sequelize.QueryTypes.SELECT
}
).then(result => {
console.log(result);
}).catch((error) => {
console.error('Failed to insert data : ', error);
});Pri nahrádzaní poľa odovzdáte metóde query() SQL dotaz a konfiguračný objekt. Obsahuje hodnotu a typ replacements. Na nahrádzané hodnoty odovzdáte údaje ako pole a tieto hodnoty zachytíte pomocou symbolu otázniku (?).
Ďalej, keďže potrebujete získať údaje o konkrétnom študentovi, student_id sa odovzdáva ako druhý parameter. Potom odovzdáte dvojicu kľúč-hodnota type: sequelize.QueryTypes.SELECT, ktorú môžete použiť na výber údajov z databázy.
Existujú aj iné typy, napríklad QueryTypes.UPDATE a QueryTypes.DELETE. V závislosti od požiadaviek si môžete vybrať typ, ktorý najlepšie vyhovuje vášmu účelu.
Nasledujúci príklad ukazuje celý kód. Tu sa pripájate k databáze a získavate vybrané údaje študenta pomocou surovej dotazu.
const {Sequelize, DataTypes} = require("sequelize");
const sequelize = new Sequelize(
'sample_student_db',
'DATABASE_USERNAME',
'DATABASE_PASSWORD',
{
host: 'DATABASE_HOST',
dialect: 'mysql'
}
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch((error) => {
console.error('Unable to connect to the database: ', error);
});
sequelize.query(
'SELECT * FROM students WHERE student_id = ?',
{
replacements: ['REPLACE_STUDENT_ID'],
type: sequelize.QueryTypes.SELECT
}
).then(result => {
console.log(result);
}).catch((error) => {
console.error('Failed to insert data : ', error);
});Uložte a zatvorte váš súbor.
Ďalej môžete tento skript spustiť pomocou nasledujúceho príkazu:
node array_raw_query.jsUvidíte výstup podobný nasledujúcemu:
Connection has been established successfully.
[ { student_id: 'STUDENT_ID_YOU_RETRIEVED',
name: 'Robert Gray',
createdAt: 2022-05-06T13:14:50.000Z,
updatedAt: 2022-05-06T13:14:50.000Z } ]Kvôli vybranému student_id sa vaše výstupné hodnoty môžu líšiť.
Nahradenie objektu
Na povrchu je výmena objektu podobná výmene poľa, ale spôsob odovzdávania údajov do surovej dotazovej metódy je odlišný. V možnosti výmeny odovzdávate údaje ako objekt a v možnosti dotazu používate hodnoty ako :key.
Na začiatok vytvorte nový súbor s názvom object_raw_query.js a vložte doň kompletné bloky kódu zo súboru server.js, pričom aktualizujte databázu na sample_student_db.
const {Sequelize, DataTypes} = require("sequelize");
const sequelize = new Sequelize(
'sample_student_db',
'DATABASE_USERNAME',
'DATABASE_PASSWORD',
{
host: 'DATABASE_HOST',
dialect: 'mysql'
}
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch((error) => {
console.error('Unable to connect to the database: ', error);
});Potom pridajte nasledujúci blok kódu na koniec nového súboru object_raw_query.js:
...
sequelize.query(
'SELECT * FROM students WHERE student_id = :id',
{
replacements: { id: 'REPLACE_STUDENT_ID' },
type: sequelize.QueryTypes.SELECT
}
).then(result => {
console.log(result);
}).catch((error) => {
console.error('Failed to insert data : ', error);
});Tu získate vybrané údaje o študentovi pomocou metódy náhrady objektu. Vytvoríte objekt replacement a nastavíte id ako informácie o študentovi, ktoré chcete získať: { id: 'REPLACE_STUDENT_ID' }.
V query() uvádzate: 'SELECT * FROM students WHERE student_id=:id'. Pri použití metódy query() odovzdávate náhradnú hodnotu ako objekt, preto sa táto metóda nazýva náhrada objektom.
Tu je kompletný kód:
const {Sequelize, DataTypes} = require("sequelize");
const sequelize = new Sequelize(
'sample_student_db',
'DATABASE_USERNAME',
'DATABASE_PASSWORD',
{
host: 'DATABASE_HOST',
dialect: 'mysql'
}
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch((error) => {
console.error('Unable to connect to the database: ', error);
});
sequelize.query(
'SELECT * FROM students WHERE student_id = :id',
{
replacements: { id: 'REPLACE_STUDENT_ID' },
type: sequelize.QueryTypes.SELECT
}
).then(result => {
console.log(result);
}).catch((error) => {
console.error('Failed to insert data : ', error);
});Uložte a zatvorte súbor.
Ďalej spustite tento skript pomocou nasledujúceho príkazu:
node object_raw_query.jsVýstup bude vyzerať podobne ako nasledujúci:
Connection has been established successfully.
[ { student_id: 'STUDENT_ID_YOU_RETRIEVED',
name: 'Robert Gray',
createdAt: 2022-05-06T13:14:50.000Z,
updatedAt: 2022-05-06T13:14:50.000Z } ]Kvôli vybranému student_id sa vaše výstupné hodnoty môžu líšiť.
V tomto kroku ste pracovali s raw dotazmi Sequelize pomocou dvoch rôznych metodík: nahradenia poľa a nahradenia objektu.
Konfigurácia premenných prostredia pre zabezpečené pripojenie k databáze
Až doteraz ste ukladali prihlasovacie údaje do databázy priamo vo vašom kóde. Hoci tento prístup funguje pri lokálnych experimentoch, nie je bezpečný. Hardcodovanie prihlasovacích údajov odhaľuje citlivé informácie, ako sú heslá k databáze a názvy hostiteľov, a zvyšuje riziko únikov, keď je kód zdieľaný alebo nasadený. V tejto časti sa naučíte, ako bezpečne ukladať tieto prihlasovacie údaje pomocou premenných prostredia.
Prečo používať environmentálne premenné?
Premenné prostredia fungujú ako externé konfiguračné parametre, ktoré vaša aplikácia môže čítať počas behu. Namiesto priameho zakódovania prihlasovacích údajov do vášho kódu sa ukladajú vo vašom systéme alebo v samostatnom konfiguračnom súbore, ktorý sa nikdy nezaradí do verziovacieho systému. Tento prístup poskytuje viacero výhod:
- Bezpečnosť: Vaše prihlasovacie údaje zostávajú skryté pred verejnými repozitármi a systémami správy verzií.
- Flexibilita: Každé prostredie (vývoj, testovanie, produkcia) môže používať odlišnú konfiguráciu databázy bez zmeny zdrojového kódu.
- Udržiavateľnosť: Centralizovaná konfigurácia umožňuje jednoduché aktualizácie, ak sa zmení heslo databázy, stačí upraviť iba jeden súbor alebo premennú.
- Zhoda: Táto prax je v súlade s metodikou Twelve-Factor App, ktorá podporuje správu konfigurácie špecifickej pre prostredie pre škálovateľné aplikácie.
Nastavenie premenných prostredia
Na správu svojich environmentálnych premenných v Node.js budete používať balík dotenv. Táto knižnica číta premenné zo súboru .env a vkladá ich do objektu process.env v Node.js, čím ich sprístupní v celej aplikácii.
Nainštalujte balík dotenv spustením nasledujúceho príkazu:
npm install dotenvPo nainštalovaní vytvorte v koreňovom adresári vášho projektu nový súbor s názvom .env. Tento súbor bude obsahovať všetky citlivé údaje potrebné na pripojenie k databáze.
Tu je príklad konfigurácie súboru .env pre vaše nastavenie Sequelize:
DB_NAME=hello_world_db
DB_USER=your_username
DB_PASSWORD=your_password
DB_HOST=localhost
DB_DIALECT=mysqlKaždá premenná zodpovedá konkrétnemu parametru, ktorý Sequelize používa na nadviazanie pripojenia.
Zabezpečenie súboru .env
Je veľmi dôležité, aby váš súbor .env nikdy nebol súčasťou verziovacieho systému. Aby ste tomu zabránili, pridajte ho do súboru .gitignore, aby ho Git pri ukladaniach zmien preskočil:
.envV produkčných prostrediach sa premenné prostredia zvyčajne konfigurujú priamo v nastaveniach vašej hostingovej platformy alebo v správcovi tajomstiev, namiesto lokálneho súboru .env.
Aktualizácia konfigurácie Sequelize
Teraz, keď ste definovali premenné prostredia, aktualizujte svoju inicializáciu Sequelize tak, aby ich používala. Začnite importovaním a konfiguráciou dotenv na začiatku hlavného súboru servera (napr. server.js):
require('dotenv').config();
const Sequelize = require('sequelize');
const sequelize = new Sequelize(
process.env.DB_NAME,
process.env.DB_USER,
process.env.DB_PASSWORD,
{
host: process.env.DB_HOST,
dialect: process.env.DB_DIALECT
}
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch((error) => {
console.error('Unable to connect to the database:', error);
});- Riadok
require('dotenv').config()načíta všetky premenné definované v súbore.envdoprocess.env. - Sequelize číta premenné prostredia pri inicializácii novej inštancie.
- Tým sa zabezpečí, že vo vašom kóde nebudú zobrazené žiadne citlivé informácie, ako sú používateľské mená alebo heslá.
Tento prístup zvyšuje bezpečnosť a umožňuje rôznym prostrediam používať jedinečné konfigurácie jednoducho zmenou hodnôt premenných prostredia.
Overovanie konfigurácie
Keď aktualizujete svoju konfiguráciu, môžete overiť pripojenie spustením svojej aplikácie Node.js:
node server.jsAk je váš súbor .env nastavený správne a server MySQL beží, uvidíte nasledujúci výstup:
Connection has been established successfully.Ak sa objaví chyba, dvakrát skontrolujte, či:
- Prihlasovacie údaje vo vašom súbore
.envzodpovedajú údajom vo vašej inštancii MySQL. - Server MySQL beží a je z vášho počítača prístupný.
- Súbor
.envsa nachádza v koreňovom adresári vášho projektu a je správne naformátovaný.
Najlepšie postupy pre bezpečné nastavenie
Používanie premenných prostredia je silný prvý krok smerom k bezpečnému riadeniu konfigurácie. Aby ste zabezpečili pokračujúcu bezpečnosť a spoľahlivosť, zvážte nasledujúce doplnkové osvedčené postupy:
- Používajte samostatné konfigurácie pre každé prostredie: Udržiavajte rôzne súbory
.envpredevelopment,stagingaproduction. Môžete ich pomenovať.env.development,.env.staginga.env.production. - Využite správcu tajomstiev: Pre produkčné prostredia používajte správcov tajomstiev namiesto ukladania tajomstiev do súborov.
- Overte premenné prostredia: Použite konfiguračný nástroj alebo spúšťací skript, ktorý skontroluje, či sú potrebné premenné definované pred spustením aplikácie. To pomáha predchádzať chybám počas behu programu.
- Pravidelne obnovujte prihlasovacie údaje: Pravidelne aktualizujte prihlasovacie údaje do databázy, aby ste znížili dopad prípadných únikov.
- Obmedzte prístup k databáze: Nakonfigurujte používateľské roly databázy tak, aby mali pre aplikáciu len nevyhnutné minimálne oprávnenia.
Implementáciou environmentálnych premenných a dodržiavaním týchto postupov zabezpečíte, že vaša aplikácia Sequelize si zachová flexibilitu aj bezpečnosť ako v prostredí vývoja, tak v produkcii.
Najlepšie postupy pri migrácii a synchronizácii
Pri vyvíjaní schémy databázy máte s Sequelize dve hlavné prístupy: písať a spúšťať explicitné migrácie alebo použiť sequelize.sync(), aby Sequelize automaticky generoval zmeny v schéme. Obe prístupy sú platné, ale slúžia rôznym účelom a majú svoje výhody a nevýhody. Poďme si vysvetliť, kedy použiť ktorý, ako písať bezpečné migrácie a ako ich spoľahlivo spúšťať vo vývoji aj v produkcii.
Migrácie verzus sequelize.sync() — kedy použiť ktorý
Migrácie (odporúčané pre produkciu): Migrácie sú explicitné, verzované zmeny vo vašom schéme. Sú uložené v zdrojovej kontrole, prechádzajú kódovou kontrolou a vykonávajú sa ako súčasť vášho nasadzovacieho procesu. Používajte migrácie v produkcii pri akejkoľvek zmene schémy, ktorá ovplyvňuje integritu alebo dostupnosť dát.
sequelize.sync()(používa sa len na vývoj a prototypy):sync()je pohodlné pre lokálny vývoj, testy a rýchle prototypy, pretože môže automaticky vytvoriť alebo upraviť tabuľky. Avšak nepoužívajtesync({ force: true })alebosync({ alter: true })v produkcii: tieto možnosti môžu vymazať dáta alebo spôsobiť nebezpečné zmeny bez riadeného spôsobu vrátenia späť.
Nástroje: sequelize-cli a nástroje na spúšťanie migrácií
Oficiálne CLI, sequelize-cli, je najjednoduchší spôsob, ako spravovať migrácie so Sequelize. Pre tímy, ktoré potrebujú väčšiu kontrolu alebo vlastné pracovné postupy, je umzug populárnou alternatívou.
Na inštaláciu a inicializáciu CLI vo vašom projekte spustite:
npm install --save-dev sequelize-cli
npx sequelize-cli initTýmto sa vytvoria nasledujúce priečinky:
config/ # Stores database configuration files
models/ # Stores your Sequelize model definitions
migrations/ # Stores migration files
seeders/ # Stores seeder files for inserting initial dataTieto priečinky by ste mali pridať do správy verzií (okrem súborov obsahujúcich prihlasovacie údaje). To zabezpečí, že každé prostredie bude konzistentne používať rovnaké zmeny v databáze.
Vytváranie a spúšťanie migrácií
Na vytvorenie nového migračného súboru použite nasledujúci príkaz:
npx sequelize-cli migration:generate --name add-isbn-to-booksTýmto sa vytvorí súbor s časovou značkou v priečinku migrations/. Otvorte súbor a definujte, čo by sa malo stať pri použití migrácie (up) a ako ju vrátiť späť (down):
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.addColumn('books', 'isbn', {
type: Sequelize.STRING
});
},
async down(queryInterface) {
await queryInterface.removeColumn('books', 'isbn');
}
};- Funkcia
upaplikuje migráciu (pridáva stĺpec). - Funkcia
downzruší zmenu (odstráni stĺpec).
Spustite migráciu pomocou:
npx sequelize-cli db:migrateAk chcete vrátiť poslednú migráciu, použite:
npx sequelize-cli db:migrate:undoV prostredí vývoja môžete tiež zrušiť všetky migrácie spustením:
npx sequelize-cli db:migrate:undo:allPísanie bezpečných, idempotentných migrácií
Pri vytváraní migrácií dodržiavajte tieto pravidlá:
Obalujte operácie do transakcií, keď to databáza podporuje. Tým sa zaistí, že migrácia buď úplne uspeje, alebo sa v prípade chyby úplne vráti späť.
module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction(async (t) => { await queryInterface.addColumn('books', 'isbn', { type: Sequelize.STRING }, { transaction: t }); }); }, async down(queryInterface) { return queryInterface.sequelize.transaction(async (t) => { await queryInterface.removeColumn('books', 'isbn', { transaction: t }); }); } };Držte migrácie malé a zamerané. Každá migrácia by mala vykonať jednu logickú zmenu (pridať stĺpec, vytvoriť index, premenovať stĺpec). Menšie migrácie sa ľahšie kontrolujú, testujú a vracajú späť.
Buďte obranní a idempotentní. Ak je to vhodné, skontrolujte existenciu, aby ste sa vyhli zlyhaniam v prostrediach s odchýlkami. Použite
queryInterface.describeTable()alebo surové dotazy na ochranu operácií.Vyhnite sa deštruktívnym operáciám na jedenkrát. Napríklad, aby ste bezpečne odstránili stĺpec, pridajte nový stĺpec, doplňte ho dátami, prepnite čítanie na nový stĺpec v aplikačnom kóde a až potom odstráňte starý stĺpec v neskoršej migrácii.
Dlhodobé migrácie bez prestojov
Veľké tabuľky a operácie s indexmi môžu spôsobiť uzamykanie. Použite tieto stratégie na minimalizovanie vplyvu:
- Najprv pridajte stĺpce, ktoré môžu byť nulové. Pridanie stĺpca, ktorý môže byť nulový, je zvyčajne rýchle. Vyhnite sa pridávaniu stĺpcov s netriviálnymi predvolenými hodnotami, ktoré spúšťajú prepis celej tabuľky.
- Dopĺňajte po malých dávkach. Implementujte pozadie úlohy na naplnenie nových stĺpcov po častiach namiesto spustenia jedného obrovského
UPDATE. - Vytvárajte indexy bez exkluzívnych zámkov, kde je to možné. Použite špecifické funkcie databázy (napríklad Postgres
CONCURRENTLYa nedávne online DDL MySQL) cez surové SQL v migráciách. - Zavádzanie pomocou funkčných vlajok. Nasadte kód aplikácie, ktorý číta nový stĺpec za funkčnou vlajkou. Po dokončení dopĺňania dát a úspešnom testovaní prepnite vlajku a neskôr odstráňte staré pole.
Návraty zmien a núdzové opravy
- Poskytnite
downmigráciu. Každéupby malo mať opačnédown, ktoré dokumentuje, ako zmeniť späť. Aj keďdownv produkcii spúšťate zriedka, slúži ako jasný plán na vrátenie zmien. - Plánujte núdzové návraty späť. Ak migrácia spôsobí problémy, buďte pripravení najprv vrátiť späť kód aplikácie a v prípade potreby obnoviť databázu zo záloh. Pravidelne testujte postupy obnovenia.
Zasievali sa dáta a zmeny schémy
- Udržiavajte seedery na minime a stabilné. Používajte seedery len pre základné vyhľadávacie alebo konfiguračné riadky. Vyhnite sa seeding veľkých objemov obchodných dát cez migrácie.
- Oddelte semienka od štrukturálnych migrácií. Ak musíte naplniť údaje, ktoré závisia od zmeny schémy, uprednostnite nasledujúci seeder, aby zostali zodpovednosti prehľadné.
CI, kontrola kódu a automatizácia nasadzovania
Najprv spustite migrácie v CI a staging prostredí. Pridajte krok v CI, ktorý spustí migrácie na dočasnej databáze, aby sa chyby zachytili včas.
Zaobchádzajte s migráciami ako s kódom. Kontrolujte a prehliadajte migračné súbory v pull requestoch. Zahrňte automatické kontroly tam, kde je to možné.
Automatizujte vykonávanie migrácií počas nasadzovania. Zabezpečte, aby sa migrácie spustili pred tým, než aplikačné procesy začnú prijímať návštevnosť. Príklad skriptov
package.json:"scripts": { "migrate": "npx sequelize-cli db:migrate", "start": "node server.js", "deploy": "npm run migrate && npm run start" }
V kontajnerových nasadeniach spúšťajte migrácie ako init kontajner alebo v nasadzovacom hooku, aby webové procesy začali až po dokončení migrácií.
Testovanie migrácií
- Otestujte oba smery. Spustite
db:migratea potomdb:migrate:undo:alllokálne aj v CI, aby ste overili, žeupajdownfungujú. - Používajte jednorazové databázy na testy. Uprednostňujte dočasné databázy alebo kontajnery pre deterministické spustenie testov.
Dodržiavanie týchto osvedčených postupov zabezpečuje, že vaše Sequelize migrácie zostanú spoľahlivé, sledovateľné a bezpečné pre dlhodobé projekty.
Riešenie problémov a tipy na výkon
Aj pri dobre nastavených aplikáciách Sequelize sa niekedy môžu vyskytnúť neočakávané problémy, ako sú chyby pripojenia k databáze, zlyhania migrácií, pomalé dotazy, zamrznutia alebo konflikty súbežnosti. Táto časť poskytuje krok za krokom návod na identifikáciu a riešenie týchto problémov spolu s osvedčenými postupmi výkonnosti, ktoré vám pomôžu udržať vašu aplikáciu stabilnú a efektívnu.
Riešenie bežných problémov
1. Chyby pripojenia
Problém: Sequelize sa nedokáže pripojiť k databáze MySQL a vypisuje chyby ako SequelizeConnectionError: connect ECONNREFUSED, Prístup zamietnutý pre používateľa alebo SequelizeHostNotFoundError.
Ako opraviť:
Začnite tým, že overíte, či sú vaše údaje o pripojení správne. Dvakrát skontrolujte hodnoty vo vašom súbore .env, vrátane názvu databázy, používateľského mena, hesla, hostiteľa a portu. Aj malá preklep alebo medzera na konci môže spôsobiť, že Sequelize sa nebude môcť pripojiť.
Ďalej sa uistite, že váš MySQL server beží a počúva na predvolený port (3306). Spojenie môžete otestovať manuálnym prihlásením:
mysql -u your_username -p -h your_host -P 3306Ak tento príkaz zlyhá, problém pravdepodobne spočíva vo vašej službe MySQL alebo prihlasovacích údajoch.
Ak používate balík dotenv, uistite sa, že require('dotenv').config() sa spúšťa predtým, než sa inicializuje Sequelize. Tento krok zabezpečí, že všetky premenné prostredia budú dostupné počas behu programu.
Nakoniec, pri vzdialených pripojeniach skontrolujte nastavenia firewallu alebo pravidlá bezpečnostnej skupiny. Server MySQL musí akceptovať prichádzajúce pripojenia z hostiteľa vašej aplikácie.
2. Zlyhania migrácie
Problém: Spustíte npx sequelize-cli db:migrate alebo sequelize.sync() a narazíte na chyby ako chýbajúce tabuľky, duplicitné stĺpce alebo nezrovnalosti v schéme.
Ako opraviť:
Problémy s migráciou zvyčajne nastávajú, keď sa súbory spúšťajú v nesprávnom poradí alebo obsahujú chyby v SQL operáciách. Sequelize spracováva migrácie na základe časových značiek v názvoch súborov, preto si overte, že súbory majú správne pomenovanie.
Ak migrácia zlyhá, podrobne si prezrite chybové hlásenie. Potom bezpečne vráťte poslednú migráciu pomocou:
npx sequelize-cli db:migrate:undoPo opravení migračného súboru ho spusťte znova.
Vždy zabaľte svoju migračnú logiku do transakcie, aby ste zabezpečili atomickosť: buď všetky zmeny prebehnú úspešne, alebo žiadna. Pred spustením migrácií na produkcii ich dôkladne otestujte na testovacej alebo lokálnej databáze, aby ste potvrdili ich správnosť.
3. Problémy so synchronizáciou modelu
Problém: Vaše modely Sequelize a schéma databázy sa nezhodujú, čo vedie k chýbajúcim stĺpcom, nesprávnym typom dát alebo zastaraným tabuľkám.
Ako opraviť:
Vyhnite sa používaniu sequelize.sync({ force: true }) v produkcii, pretože to zmaže a znovu vytvorí tabuľky, čo spôsobí nezvratnú stratu dát. Podobne používajte sequelize.sync({ alter: true }) opatrne; môže to nepredvídateľne meniť schémy.
Namiesto toho uprednostnite explicitné migrácie, ktoré jasne definujú každú zmenu schémy. Na porovnanie vašich modelov s aktuálnou štruktúrou databázy použite:
await queryInterface.describeTable('tableName');To pomáha identifikovať nezrovnalosti skôr, než ovplyvnia výrobu.
4. Chyby dotazu a časového limitu
Problém: Vidíte chyby súvisiace s časovým limitom, ako napríklad Časový limit pripojenia alebo Príliš veľa pripojení.
Ako opraviť:
Problémy s vypršaním časového limitu sú často spôsobené vyčerpanými spojovacími bazénmi alebo nezatvorenými spojeniami. Uistite sa, že všetky Sequelize dotazy sú správne očakávané, aby sa spojenia po použití vrátili do bazéna.
Môžete tiež doladiť konfiguráciu poolu Sequelize tak, aby lepšie vyhovovala pracovnej záťaži vašej aplikácie:
const sequelize = new Sequelize(DB_NAME, DB_USER, DB_PASSWORD, {
host: DB_HOST,
dialect: 'mysql',
pool: {
max: 10,
min: 0,
acquire: 30000,
idle: 10000
}
});Ak vaša aplikácia spracováva veľa súbežných používateľov, zvážte zvýšenie parametra max_connections v konfigurácii vašej databázy MySQL. Sledujte aktívne pripojenia pomocou SHOW PROCESSLIST; v MySQL, aby ste zistili úniky alebo nepoužívané relácie.
5. Pomalý výkon dotazu
Problém: Niektoré dotazy trvajú výrazne dlhšie, než sa očakávalo, čo spôsobuje pomalé odpovede API alebo vysokú latenciu.
Ako diagnostikovať:
Začnite tým, že zistíte, ktoré dotazy sú pomalé. Môžete zaznamenať všetky dotazy, ktoré Sequelize vykonáva, dočasným povolením logovania:
const sequelize = new Sequelize(..., { logging: console.log });Potom použite príkaz EXPLAIN MySQL, aby ste pochopili, ako databáza vykonáva dotaz:
EXPLAIN SELECT * FROM users WHERE email = 'user@example.com';Ak výstup zobrazuje „úplné prehľadávanie tabuľky“, dotazu chýba index.
Môžete tiež povoliť protokol pomalých dotazov MySQL, aby sa automaticky zaznamenávali pomalé operácie:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;Ako opraviť:
Pridajte indexy na stĺpce, ktoré sa často dotazujú (najmä tie, ktoré sa používajú v klauzulách WHERE, JOIN a ORDER BY). Vyhnite sa SELECT *, namiesto toho explicitne získajte iba polia, ktoré potrebujete, pomocou možnosti attributes.
Ak Sequelize generuje neefektívne dopyty s nepotrebnými spojeniami, prepíšte dopyt pomocou čistého SQL. Pri veľkých reportoch alebo analytických dopytoch ich rozdeľte na menšie kroky alebo použite nástroje na cachovanie, ako je Redis, na uloženie opakujúcich sa výsledkov.
6. Záseky a chyby súbežnosti
Problém: Dostávate chyby ako Deadlock found when trying to get lock; try restarting transaction, najmä pri vysokom zaťažení.
Ako diagnostikovať:
Skontrolujte stav InnoDB v MySQL, aby ste zistili, ktoré dotazy alebo tabuľky boli zapojené:
SHOW ENGINE INNODB STATUS\GTento výstup obsahuje podrobné informácie o nedávnych zamrznutiach a čakaniach na zámky. Môžete tiež zapnúť všeobecné alebo transakčné záznamy, aby ste si mohli prezrieť postupnosť dotazov vedúcich k problému.
Ako opraviť:
Dopady mŕtvej slučky nastávajú, keď dve alebo viac transakcií čakajú na zámky druhej strany. Aby sa minimalizovali:
Udržiavajte transakcie čo najkratšie. Nevolajte externé služby ani nevykonávajte náročné výpočty počas držania zámku.
Vždy pristupujte k tabuľkám a riadkom v rovnakom poradí vo všetkých transakciách, aby ste sa vyhli vzájomnému blokovaniu.
Pre opakujúce sa zablokovania implementujte jednoduchý mechanizmus opakovania s exponenciálnym oneskorením:
async function runWithRetry(fn, retries = 3) { for (let i = 0; i < retries; i++) { try { return await fn(); } catch (err) { if (isDeadlockError(err) && i < retries - 1) { await sleep(100 * (i + 1)); continue; } throw err; } } }Používajte zámky na úrovni riadkov (
SELECT ... FOR UPDATE) iba keď je to potrebné, a uvoľnite ich okamžite.Rozdeľte veľké transakcie na menšie dávky, aby sa znížila konkurencia.
Podľa potreby upravte úrovne izolácie transakcií, ale až po potvrdení, že to neovplyvní konzistenciu údajov.
Tipy na optimalizáciu výkonu
Problémy s výkonom často vyplývajú z neefektívnych dopytov, chýbajúcich indexov alebo zlého riadenia pripojenia. Tu je niekoľko praktických tipov, ako zlepšiť výkon Sequelize bez toho, aby ste obetovali prehľadnosť alebo udržiavateľnosť.
1. Optimalizujte dopyty
Píšte dotazy, ktoré vyžadujú iba to, čo je potrebné. Sťahovanie zbytočných dát zvyšuje použitie pamäte a spomaľuje odpovede. Použite attributes na obmedzenie polí:
const users = await User.findAll({ attributes: ['id', 'name'] });Vždy filtrujte výsledky pomocou indexovaných stĺpcov a vyhýbajte sa širokým vyhľadávaniam ako LIKE '%term%', kedykoľvek je to možné.
2. Efektívne používanie indexov
Indexy zrýchľujú vyhľadávanie, ale môžu spomaliť zápisy. Pridávajte indexy len tam, kde prinášajú merateľný prínos. Analyzujte výkon dotazov pomocou MySQL EXPLAIN, aby ste overili zlepšenia pred a po pridania indexu:
await queryInterface.addIndex('users', ['email']);3. Ladenie pripojovacieho poolu
Pool pripojení určuje, koľko databázových pripojení Sequelize udržiava.
- Pre malé aplikácie je zvyčajne dostatočných 5–10 pripojení.
- Pre systémy s vysokou záťažou zväčšite veľkosť poolu a upravte časové limity, aby ste predišli úzkym miestam v pripojeniach. Pravidelne sledujte využitie pomocou MySQL príkazu
SHOW PROCESSLIST;.
4. Povoliť zaznamenávanie a monitorovanie
Dočasne zapnite zaznamenávanie v Sequelize, aby ste mohli skontrolovať SQL dotazy. Použite pomalý log dotazov MySQL na identifikáciu dotazov, ktoré prekračujú váš výkonový limit. Pre sledovanie v reálnom čase integrujte monitorovacie nástroje, ako sú PM2, New Relic alebo Datadog, na meranie latencie a využitia zdrojov.
5. Ukladať často používané dotazy do cache
Ukladajte výsledky do vyrovnávacej pamäte pre dáta, ktoré sa často nemenia. Nástroje ako Redis alebo Memcached znižujú počet volaní databázy a zlepšujú dobu odozvy, najmä pri pracovných zaťaženiach so zameraním na čítanie.
6. Číslovať výsledky
Veľké množiny výsledkov spotrebúvajú značnú pamäť. Vždy stránkujte dotazy v API:
const users = await User.findAll({ limit: 50, offset: 100 });Stránkovanie udržiava odpovede ľahké a konzistentné aj pri zaťažení.
7. Používajte surové dotazy pre zložité operácie
Ak abstrakcia Sequelize vedie k neefektívnemu SQL pre konkrétny prípad použitia, vykonajte priamo surový SQL dotaz:
const [results] = await sequelize.query('SELECT name FROM users WHERE active = 1');Používajte surové dotazy striedmo a jasne ich dokumentujte pre budúcu údržbu.
Často kladené otázky
1. Čo je Sequelize v Node.js?
Sequelize je objektovo-relačný mapovač (ORM) pre Node.js, ktorý poskytuje vysokú úroveň API založeného na JavaScripte pre prácu s SQL databázami, ako sú MySQL, PostgreSQL, SQLite a MariaDB. Namiesto písania surového SQL pre každú operáciu definujete modely, ktoré sa mapujú na databázové tabuľky, a používate metódy modelov na vkladanie, dotazovanie, aktualizáciu a mazanie záznamov. Sequelize tiež podporuje asociácie (vztahy medzi modelmi), transakcie, migrácie a surové dotazy, keď potrebujete priamy SQL.
2. Ako pripojím Sequelize k MySQL?
Aby ste pripojili Sequelize k MySQL, vytvoríte inštanciu Sequelize s prihlasovacími údajmi a možnosťami databázy. V súbore Node.js vyžadujte Sequelize, voliteľne načítajte premenné prostredia a potom ho inicializujte s názvom databázy, používateľským menom, heslom a možnosťami hostiteľa/dialektu. Napríklad:
require('dotenv').config();
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize(
process.env.DB_NAME,
process.env.DB_USER,
process.env.DB_PASSWORD,
{
host: process.env.DB_HOST || 'localhost',
dialect: 'mysql'
}
);
await sequelize.authenticate();
console.log('Connected to the database successfully!');Vždy uchovávajte prihlasovacie údaje mimo správy zdrojového kódu (napríklad v súbore .env alebo v správcovi tajomstiev).
3. Ako vytvoriť a synchronizovať modely v Sequelize?
V Sequelize modely reprezentujú tabuľky. Definujete ich pomocou sequelize.define() alebo rozšírením triedy Model. Potom ich môžete synchronizovať s vašou databázou, takže Sequelize automaticky vytvorí tabuľky (skvelé na vývoj). Tu je malý príklad:
const { DataTypes } = require('sequelize');
const Book = sequelize.define('Book', {
title: { type: DataTypes.STRING, allowNull: false },
author: { type: DataTypes.STRING, allowNull: false },
releaseDate: DataTypes.DATEONLY
});
// Create the table if it does not exist
await sequelize.sync();Pre produkčné prostredia je lepšie používať migrácie, aby ste mali verziu riadenú kontrolu nad zmenami schémy.
4. Ako používam Sequelize s Express?
V aplikácii Express inicializujte Sequelize v samostatnom súbore (napr. db.js), exportujte pripojenú inštanciu a modely a importujte ich kdekoľvek ich potrebujete vo svojich routových handleroch alebo kontroléroch. V routových handleroch používajte async/await na volanie metód modelov Sequelize a chyby spracovávajte pomocou try/catch alebo prostredníctvom error middleware. Takto to vyzerá v praxi:
// db.js
const sequelize = new Sequelize(...);
const User = sequelize.define(...);
module.exports = { sequelize, User };
// app.js
const { User } = require('./db');
app.get('/users', async (req, res) => {
const users = await User.findAll();
res.json(users);
});Uistite sa, že ste spustili migrácie alebo zavolali sequelize.sync() pred spustením vášho Express servera, aby vaše databázové tabuľky existovali, keď prídu požiadavky.
5. Aký je rozdiel medzi Sequelize a priamymi SQL dotazmi?
Sequelize vám umožňuje písať logiku databázy v JavaScripte, zatiaľ čo čistý SQL znamená písanie SQL príkazov priamo. Sequelize robí váš kód čistejším a ľahšie udržiavateľným, pretože môžete definovať modely a vzťahy raz a používať ich naprieč celou aplikáciou. Čistý SQL vám dáva väčšiu kontrolu a niekedy môže byť rýchlejší pri veľmi zložitých dopytoch.
Stručne povedané, používajte Sequelize pre väčšinu bežných úloh a surový SQL použite, keď potrebujete optimalizovať výkon alebo vykonať niečo, čo Sequelize nedokáže ľahko vyjadriť.
6. Ako môžem definovať asociácie v Sequelize?
Sequelize uľahčuje opisovanie vzťahov medzi tabuľkami. Môžete nastaviť vzťahy jeden k jednému, jeden k mnohým alebo mnoho k mnohým pomocou jednoduchých metód ako hasOne, hasMany a belongsToMany. Napríklad:
// One to one
User.hasOne(Profile);
Profile.belongsTo(User);
// One to many
Author.hasMany(Book);
Book.belongsTo(Author);
// Many to many
Student.belongsToMany(Course, { through: 'StudentCourse' });
Course.belongsToMany(Student, { through: 'StudentCourse' });Akonáhle je definované, môžete vo svojich dotazoch používať include na automatické získavanie súvisiacich údajov.
7. Ako zvládam migrácie a zmeny schémy?
Vo vývoji môžete použiť sequelize.sync() na rýchle vytvorenie tabuliek. Ale vo výrobnom prostredí by ste mali vždy používať migrácie. Migrácie sú verzované súbory, ktoré popisujú, ako sa schéma databázy mení v priebehu času, podobne ako Git commit zaznamenáva zmeny v kóde.
S CLI nástrojom Sequelize môžete vytvoriť migráciu:
npx sequelize-cli migration:generate --name add-users-tableKaždá migrácia má metódy up a down, jedna na aplikovanie zmeny a druhá na jej vrátenie. Spustite svoje migrácie s:
npx sequelize-cli db:migrateTýmto spôsobom má každý vo vašom tíme (a každé nasadenie) rovnakú štruktúru databázy.
Použite sequelize.sync() na rýchle experimenty, ale po spustení aplikácie sa držte migrácií, pretože sú bezpečnejšie, vratné a ľahšie sledovateľné.
Záver
V tomto návode ste nastavili Sequelize s Node.js a MySQL na správu údajov prostredníctvom modelov, asociácií a migrácií. Tiež ste zabezpečili svoje prístupové údaje k databáze pomocou premenných prostredia a preskúmali najlepšie postupy pri riešení problémov a optimalizácii výkonu.
S týmito krokmi máte teraz pevný základ pre vytváranie a udržiavanie bezpečných a efektívnych aplikácií Node.js, ktoré používajú Sequelize a MySQL na správu údajov.
Ak sa chcete dozvedieť viac o Sequelize, pozrite si dokumentáciu produktu. Pre viac takýchto tutoriálov o Node.js si pozrite nasledujúce články:
- Ako nastaviť GraphQL server v Node.js s Apollo Server a Sequelize
- Ako implementovať cache v Node.js pomocou Redis
- Ako vytvoriť webový server v Node.js pomocou modulu HTTP
Ďakujeme, že sa učíte s komunitou Linux-Console.net.
