Node.js İle Sequelize Kullanarak Veritabanı Migrasyon Yönetimi Nasıl Yapılır?

Node.js İle Sequelize Kullanarak Veritabanı Migrasyon Yönetimi Nasıl Yapılır?
Node.js İle Sequelize Kullanarak Veritabanı Migrasyon Yönetimi Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Projeye başlamadan önce bilgisayarınızda Node.js'in güncel bir sürümünün (LTS 2026) yüklü olması gerekir. Ayrıca veritabanı olarak PostgreSQL veya MySQL kullanmanızı öneririz. Sequelize CLI (Command Line Interface), migrasyon dosyalarını yönetmek için kullanacağımız temel araçtır.

Projenizi başlatmak ve gerekli paketleri kurmak için şu komutları terminalinizde çalıştırın:

mkdir node-sequelize-migration
cd node-sequelize-migration
npm init -y
npm install sequelize sequelize-cli pg pg-hstore
npx sequelize-cli init

Bu komutlar, projenizin kök dizininde config, models, migrations ve seeders klasörlerini oluşturacaktır. config/config.json dosyasında veritabanı bağlantı bilgilerinizi kendi ortamınıza göre güncellemeyi unutmayın.

Sequelize CLI ile İlk Migrasyon Dosyasını Oluşturma

Migrasyonlar, veritabanı üzerinde yapılacak işlemleri tanımlayan JavaScript dosyalarıdır. Bir tablo oluşturmak için migration:generate komutunu kullanırız. Örneğin, bir "Kullanıcılar" tablosu oluşturalım:

npx sequelize-cli migration:generate --name create-users

Bu komut, migrations klasörü altında zaman damgalı bir dosya oluşturur. Bu dosya içerisinde up ve down fonksiyonları bulunur. up fonksiyonu değişiklikleri uygulamak için, down fonksiyonu ise yapılan değişikliği geri almak (rollback) için kullanılır.

Migrasyon Dosyasını Yapılandırma ve Tablo Tanımlama

Oluşturulan dosyanın içeriğini, veritabanı şemanıza göre düzenlemeniz gerekir. Aşağıdaki örnekte, id, username, email ve createdAt alanlarına sahip bir kullanıcı tablosu tanımlıyoruz:

'use strict';
module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.createTable('Users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      username: {
        type: Sequelize.STRING,
        allowNull: false
      },
      email: {
        type: Sequelize.STRING,
        allowNull: false,
        unique: true
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: async (queryInterface, Sequelize) => {
    await queryInterface.dropTable('Users');
  }
};

Bu yapıda queryInterface, Sequelize'in veritabanı şemasını manipüle etmek için sunduğu temel arayüzdür. up fonksiyonunda tabloyu oluştururken, down fonksiyonunda ise hata durumunda veya geri alma işleminde tablonun nasıl silineceğini belirtiyoruz.

Migrasyonları Çalıştırma ve Veritabanına Uygulama

Hazırladığınız migrasyonu veritabanına uygulamak için db:migrate komutunu kullanırız. Bu komut, henüz çalıştırılmamış tüm migrasyonları sırasıyla veritabanına işler.

npx sequelize-cli db:migrate

Bu işlemden sonra veritabanınızda SequelizeMeta adında bir tablo oluşacaktır. Bu tablo, hangi migrasyonların başarıyla çalıştırıldığını takip eder. Eğer bir hata yaparsanız ve son işlemi geri almak isterseniz, db:migrate:undo komutunu kullanabilirsiniz.

Komut Açıklama Kullanım Amacı
db:migrate Tüm bekleyen migrasyonları çalıştırır. Üretim ve geliştirme ortamları.
db:migrate:undo En son çalıştırılan migrasyonu geri alır. Hata düzeltme süreci.
db:migrate:status Migrasyonların durumunu listeler. Kontrol ve takip.

Var Olan Tabloya Sütun Ekleme (Migration Modifikasyonu)

Projeniz ilerledikçe mevcut tablolara yeni alanlar eklemeniz gerekecektir. Bunun için yeni bir migrasyon dosyası oluşturmalısınız. Asla var olan migrasyon dosyasını değiştirmeyin; yeni bir dosya oluşturmak veritabanı tutarlılığı için kritiktir.

npx sequelize-cli migration:generate --name add-age-to-users

Yeni oluşturulan dosyada addColumn metodunu kullanarak age sütununu ekleyelim:

'use strict';
module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.addColumn('Users', 'age', {
      type: Sequelize.INTEGER,
      allowNull: true
    });
  },
  down: async (queryInterface, Sequelize) => {
    await queryInterface.removeColumn('Users', 'age');
  }
};

Bu işlem, veritabanındaki mevcut verileri bozmadan yeni bir sütun eklemenize olanak tanır. down fonksiyonunda ise removeColumn kullanarak işlemi geri almayı garanti altına almış oluyoruz.

Güvenlik Uyarısı: Üretim (production) ortamında migrasyonları çalıştırmadan önce mutlaka veritabanı yedeği alınız. Hassas verileri içeren tablolarda sütun silme veya veri tipi değiştirme işlemleri sırasında veri kaybı yaşanabilir. Her zaman önce geliştirme ortamında test edin.

Sıkça Sorulan Sorular

Migrasyon dosyasını yanlış yazdım, nasıl düzeltebilirim?

Eğer migrasyon henüz veritabanına uygulanmadıysa dosyayı doğrudan düzenleyebilirsiniz. Ancak uygulanmışsa, db:migrate:undo ile geri alıp dosyayı güncelledikten sonra tekrar çalıştırın.

SequelizeMeta tablosu ne işe yarar?

Bu tablo, veritabanında hangi migrasyonların halihazırda çalıştırıldığını tutar. Sequelize, bu tabloyu kontrol ederek mükerrer migrasyon çalıştırılmasını engeller.

Üretim ortamında migrasyonları nasıl yönetmeliyim?

Üretim ortamında migrasyonları manuel çalıştırmak yerine, CI/CD süreçlerinize (GitHub Actions, GitLab CI vb.) entegre ederek otomatik çalıştırılmalarını sağlamalısınız.

Veritabanı şeması ile model dosyaları senkronize olmalı mı?

Evet, Sequelize modelleriniz ile migrasyon dosyalarınız aynı yapıyı temsil etmelidir. Migrasyonlar veritabanını, modeller ise uygulamanın veriye erişim katmanını yönetir.

Seeders nedir ve migrasyonlardan farkı nedir?

Migrasyonlar şema değişiklikleri (DDL) içindir; Seeders ise veritabanına başlangıç verileri (DML) eklemek için kullanılır.

Yasal Uyarı: Bu rehber genel yazılım eğitimi amaçlıdır. Kod güvenliği, SQL injection'a karşı korunma ve veri gizliliği geliştiricinin sorumluluğundadır. Sequelize, parametreli sorgular kullanarak SQL injection riskini otomatik olarak azaltır; ancak karmaşık ham sorgularda (raw queries) dikkatli olunmalıdır.

İleri Seviye Migrasyon Stratejileri ve Hata Ayıklama

Profesyonel projelerde migrasyonlar sadece tablo oluşturmakla sınırlı değildir. Veri bütünlüğünü korumak ve kesintisiz dağıtım (deployment) süreçlerini yönetmek için bazı ileri tekniklere hakim olmanız gerekir. Özellikle veritabanı şemasında büyük değişiklikler yaparken verilerin kaybolmaması için queryInterface nesnesinin sunduğu gelişmiş fonksiyonları kullanmalısınız.

Veri Taşıma (Data Migration) Teknikleri

Bir sütunu silmeden önce içindeki veriyi başka bir yere aktarmanız veya yeni bir sütuna dönüştürmeniz gerekebilir. Bu tür durumlarda migrasyon dosyası içerisinde ham SQL sorguları çalıştırmak veya Sequelize modellerini kullanmak yerine queryInterface.sequelize.query metodunu tercih etmelisiniz.

// Migrasyon dosyasında veri taşıma örneği
module.exports = {
  up: async (queryInterface, Sequelize) => {
    // Önce yeni sütunu ekle
    await queryInterface.addColumn('Users', 'fullName', {
      type: Sequelize.STRING,
      allowNull: true
    });

    // Veriyi taşı
    await queryInterface.sequelize.query(
      'UPDATE "Users" SET "fullName" = "firstName" || \' \' || "lastName"'
    );
  },
  down: async (queryInterface, Sequelize) => {
    await queryInterface.removeColumn('Users', 'fullName');
  }
};

Migrasyon Hata Ayıklama ve Geri Alma (Rollback) Stratejileri

Bazen migrasyonlar, veritabanındaki mevcut kısıtlamalar (constraints) veya veri tipi uyuşmazlıkları nedeniyle başarısız olabilir. Sequelize, bir migrasyon başarısız olduğunda işlemi otomatik olarak durdurur ancak veritabanı yarıda kalmış bir durumda olabilir. Bu gibi durumlarda sequelize db:migrate:undo komutu hayat kurtarıcıdır.

İpucu: Eğer bir migrasyon dosyasını yanlışlıkla düzenlediyseniz ve veritabanı ile senkronizasyon bozulduysa, SequelizeMeta tablosundan ilgili kaydı manuel olarak silerek migrasyonu tekrar çalıştırmayı deneyebilirsiniz. Ancak bu yöntem sadece geliştirme ortamında önerilir.

CI/CD Süreçlerinde Otomatik Migrasyon Yönetimi

Modern yazılım geliştirme süreçlerinde, kodunuzu canlı ortama (production) alırken migrasyonların manuel olarak çalıştırılması hata payını artırır. Bu süreci otomatize etmek için CI/CD pipeline'ınıza migrasyon adımlarını eklemelisiniz.

Otomasyon İçin En İyi Uygulamalar

  • Pre-deployment: Uygulama ayağa kalkmadan önce migrasyonları çalıştıran bir script (örneğin npx sequelize-cli db:migrate) tanımlayın.
  • Yedekleme: Her migrasyon öncesi veritabanı yedeği almayı alışkanlık haline getirin.
  • Dry Run: Karmaşık migrasyonları önce staging ortamında test edin.

Aşağıdaki örnek, bir Node.js uygulamasının başlangıç dosyasında (index.js veya server.js) migrasyonların otomatik tetiklenmesi için kullanılan basit bir yapıyı göstermektedir:

const { execSync } = require('child_process');

function runMigrations() {
  try {
    console.log('Migrasyonlar başlatılıyor...');
    execSync('npx sequelize-cli db:migrate', { stdio: 'inherit' });
    console.log('Migrasyonlar başarıyla tamamlandı.');
  } catch (error) {
    console.error('Migrasyon hatası:', error);
    process.exit(1);
  }
}

// Uygulamayı başlatmadan önce çalıştır
runMigrations();
startServer();

Bu yöntem, özellikle konteyner tabanlı (Docker/Kubernetes) yapılarda, uygulama konteyneri ayağa kalkarken veritabanı şemasının her zaman güncel kalmasını sağlar.

Sonuç

Node.js ile Sequelize kullanarak migrasyon yönetimi yapmak, veritabanı değişikliklerinizi profesyonel ve hatasız bir şekilde yönetmenize olanak tanır. Bu rehberde, bir projenin kurulumundan başlayarak tablo oluşturma, sütun ekleme ve migrasyonların geri alınması süreçlerini adım adım inceledik. Bir sonraki adım olarak, Sequelize ile ilişkisel veritabanı modelleri (One-to-Many, Many-to-Many) kurmayı ve veritabanı sorgularını optimize etmeyi öğrenerek yetkinliklerinizi bir üst seviyeye taşıyabilirsiniz.

Bu yazıya tepkinizi paylaşın:
Emre Yılmaz

Bilgi odaklı nasıl yapılır içerikleriyle karmaşık süreçleri herkes için anlaşılır kılıyorum. Okuyucularımın zamanını verimli kullanmalarını sağlayan stratejiler geliştiriyorum.

Yorumlar (0)

Yorum Yaz