PostgreSQL — pg moduli, connection pool
Ma'lumotlar bazasi nima uchun kerak?
Oldingi darslarda ma'lumotlarni xotirada saqladik — massiv ichida. Bu faqat server ishlayotgan vaqtda mavjud. Server qayta ishga tushsa — hamma narsa yo'qoladi.
Haqiqiy ilovada ma'lumotlar doimiy saqlanishi kerak. Buning uchun ma'lumotlar bazasi ishlatiladi. PostgreSQL — eng kuchli va keng tarqalgan ochiq manbali relyatsion ma'lumotlar bazasi.
pg moduli nima?
pg — Node.js dan PostgreSQL ga ulanish uchun rasmiy kutubxona. U Node.js va PostgreSQL o'rtasidagi ko'prik: siz JavaScript yozasiz, pg uni PostgreSQL tushungan formatga aylantiradi, natijani qaytaradi.
npm install pg
Ulanish — oddiy va pool
PostgreSQL ga ulanishning ikki usuli bor. Farqini tushunish muhim.
Oddiy ulanish — har so'rov uchun yangi ulanish ochiladi, tugagach yopiladi. Xuddi har safar do'konga borganda yangi yo'l qurish kabi — isrof va sekin.
Connection Pool — bir nechta ulanish oldindan ochiladi va qayta ishlatiladi. Xuddi taksi parki kabi — mashina bo'sh bo'lsa, darhol beriladi. Tugagach qaytariladi, boshqasiga beriladi.
Production da har doim pool ishlatiladi. Oddiy ulanish faqat skriptlar yoki bir martalik ishlar uchun.
// db.js
const { Pool } = require('pg');
const pool = new Pool({
host: process.env.DB_HOST || 'localhost',
port: process.env.DB_PORT || 5432,
database: process.env.DB_NAME || 'mydb',
user: process.env.DB_USER || 'postgres',
password: process.env.DB_PASSWORD || 'secret',
max: 10, // maksimal ulanishlar soni
idleTimeoutMillis: 30000, // 30 soniya bo'sh tursa — yopiladi
});
module.exports = pool;
Bu fayl bir marta yaratiladi va butun loyihada ishlatiladi. pool ob'ekti ulanishlarni o'zi boshqaradi — siz har safar ulanish ochib-yopmasangiz ham bo'ladi.
Birinchi so'rov
const pool = require('./db');
async function getUsers() {
const result = await pool.query('SELECT * FROM users');
return result.rows; // natija — ob'ektlar massivi
}
pool.query() — SQL so'rovini bajaradi va natijani qaytaradi. result.rows — qatorlar massivi. Har bir qator — JavaScript ob'ekti, ustun nomlari kalit sifatida.
Masalan, users jadvalida id, name, email ustunlari bo'lsa:
result.rows
// [
// { id: 1, name: 'Ali', email: 'ali@example.com' },
// { id: 2, name: 'Vali', email: 'vali@example.com' },
// ]
Express bilan birlashtirish
// routes/users.js
const express = require('express');
const router = express.Router();
const pool = require('../db');
router.get('/', async (req, res, next) => {
try {
const result = await pool.query('SELECT id, name, email FROM users');
res.json(result.rows);
} catch (err) {
next(err);
}
});
router.get('/:id', async (req, res, next) => {
try {
const result = await pool.query(
'SELECT id, name, email FROM users WHERE id = $1',
[req.params.id]
);
if (result.rows.length === 0) {
return res.status(404).json({ message: 'Topilmadi' });
}
res.json(result.rows[0]);
} catch (err) {
next(err);
}
});
module.exports = router;
$1, $2 — parametrlar. Qiymatlar ikkinchi argument — massiv sifatida beriladi. Bu SQL Injection dan himoya qiladi. Keyingi darsda batafsil.
Ulanishni tekshirish
Server ishga tushganda ma'lumotlar bazasiga ulanish muvaffaqiyatli bo'lganini tekshirish — yaxshi amaliyot:
// app.js
const pool = require('./db');
async function startServer() {
try {
await pool.query('SELECT 1'); // oddiy test so'rov
console.log('Ma\'lumotlar bazasiga ulandi');
app.listen(3000, () => {
console.log('Server ishlamoqda');
});
} catch (err) {
console.error('Ma\'lumotlar bazasiga ulanib bo\'lmadi:', err.message);
process.exit(1); // ulanmasa — server ishga tushmaydi
}
}
startServer();
Nima uchun bu muhim? Ma'lumotlar bazasiz server ishga tushsa — so'rovlar keladi, lekin hamma narsa xato beradi. Yaxshisi darhol to'xtatib, muammoni hal qilish.
Tez-tez uchraydigan xatolar
Parolni kod ichiga yozish:
// Xato — GitHub ga chiqsa, parol oshkor bo'ladi:
const pool = new Pool({ password: 'mysecretpassword' });
// To'g'ri — .env faylidan:
const pool = new Pool({ password: process.env.DB_PASSWORD });
result.rows o'rniga result qaytarish:
// Xato:
return result; // { rows: [...], rowCount: 2, ... } — keraksiz ma'lumotlar
// To'g'ri:
return result.rows; // faqat qatorlar
Bitta qator kutilganda massiv qaytarish:
// Xato:
const user = await pool.query('SELECT * FROM users WHERE id = $1', [id]);
return user; // massiv, ob'ekt emas
// To'g'ri:
const result = await pool.query('SELECT * FROM users WHERE id = $1', [id]);
return result.rows[0]; // birinchi (va yagona) qator
Xulosa
pg — Node.js dan PostgreSQL ga ulanish uchun. Connection Pool — ulanishlarni qayta ishlatadi, har so'rov uchun yangi ulanish ochilmaydi.
pool.query(sql, params) — SQL so'rovini bajaradi. Natija result.rows da — ob'ektlar massivi.
Parametrlar $1, $2 ko'rinishida — SQL Injection dan himoya.
Keyingi dars
14-dars: PostgreSQL — CRUD, parametrli so'rovlar, SQL Injection himoyasi