Python İle Sqlalchemy Kütüphanesi Kullanarak Veritabanı Migrasyonu Nasıl Yapılır?

Python İle Sqlalchemy Kütüphanesi Kullanarak Veritabanı Migrasyonu Nasıl Yapılır?
Python İle Sqlalchemy Kütüphanesi Kullanarak Veritabanı Migrasyonu Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Çalışmaya başlamadan önce sisteminizde Python 3.10 veya daha güncel bir sürümün kurulu olduğundan emin olmalısınız. SQLAlchemy ve Alembic kütüphanelerini kurmak için terminalinizde aşağıdaki komutu çalıştırmanız yeterlidir:

pip install sqlalchemy alembic psycopg2-binary

Burada sqlalchemy veritabanı etkileşimi için temel kütüphanemizdir. alembic ise migrasyonları yöneten araçtır. psycopg2-binary ise PostgreSQL veritabanı sürücüsü olarak örnekte kullanılacaktır. Eğer farklı bir veritabanı (SQLite veya MySQL) kullanıyorsanız ilgili sürücüleri yüklemelisiniz.

Alembic ile Proje Yapısını Başlatma

Projenizde migrasyonları yönetmeye başlamak için öncelikle bir Alembic ortamı oluşturmanız gerekir. Bu işlem, projenizde alembic klasörünü ve gerekli konfigürasyon dosyalarını oluşturur.

alembic init alembic

Bu komut, projenizin kök dizininde alembic.ini dosyasını ve alembic/ klasörünü oluşturacaktır. alembic.ini dosyası, veritabanı bağlantı dizginizi (connection string) tutan temel ayar dosyasıdır.

Veritabanı Bağlantısı ve Konfigürasyon

Alembic'in veritabanınızla konuşabilmesi için alembic/env.py dosyasında SQLAlchemy modelinizin meta verilerini tanımlamanız gerekir. Bu adım, migrasyon aracının modellerinizdeki değişiklikleri otomatik olarak algılamasını sağlar.

# alembic/env.py içerisinde ilgili bölüme ekleyin
from my_app.models import Base
target_metadata = Base.metadata

# sqlalchemy.url ayarını alembic.ini dosyasında güncelleyin
# sqlalchemy.url = postgresql://kullanici:sifre@localhost/veritabani_adi

Burada target_metadata değişkenini kendi SQLAlchemy Base sınıfınızın metadata'sına eşitleyerek, Alembic'in modellerinizi tanımasını sağladık.

İlk Migrasyon Dosyasını Oluşturma

Modellerinizi oluşturduktan sonra, bu modelleri veritabanına yansıtmak için ilk migrasyon dosyanızı oluşturmalısınız. Alembic, mevcut modelleriniz ile veritabanı arasındaki farkı otomatik olarak algılayabilir.

alembic revision --autogenerate -m "İlk veritabanı kurulumu"

Bu komut, alembic/versions/ klasörü altında bir Python dosyası oluşturur. Bu dosya, veritabanında hangi işlemlerin (tablo oluşturma, sütun ekleme gibi) yapılacağını içeren upgrade() ve downgrade() fonksiyonlarını barındırır.

Migrasyonu Uygulama ve Test Etme

Oluşturulan migrasyon dosyasını veritabanına uygulamak için upgrade komutunu kullanırız. Bu işlem, tanımladığınız SQLAlchemy modellerini fiziksel veritabanına işler.

alembic upgrade head

Bu komutu çalıştırdıktan sonra veritabanı yönetim aracınızla (örneğin pgAdmin veya DBeaver) tabloların oluşup oluşmadığını kontrol edebilirsiniz. Eğer bir hata ile karşılaşırsanız veya bir değişiklikten vazgeçerseniz alembic downgrade -1 komutu ile bir önceki sürüme geri dönebilirsiniz.

Migrasyon Yöntemlerinin Karşılaştırılması

Yöntem Avantaj Dezavantaj
Manuel SQL Tam kontrol sağlar Hata payı yüksek, yönetimi zor
Alembic (Otomatik) Hızlı, hatasız, versiyonlanabilir Karmaşık geçişlerde manuel müdahale gerektirir
SQLAlchemy create_all() Küçük projeler için pratik Veri kaybı riski, üretim ortamı için uygun değil

Güvenlik ve Üretim Ortamı Uyarıları

Kritik Uyarı: Üretim (production) ortamlarında veritabanı şemasını doğrudan kod üzerinden (create_all gibi) oluşturmayın. Her zaman Alembic gibi bir migrasyon aracı kullanın. Ayrıca, veritabanı şifrelerinizi asla kod içerisinde açık metin olarak saklamayın; .env dosyaları veya ortam değişkenleri (environment variables) kullanın.

Sıkça Sorulan Sorular

Alembic neden SQLAlchemy ile birlikte kullanılmalı?

SQLAlchemy veritabanı etkileşimi için harikadır ancak şema değişikliklerini takip etmez. Alembic, bu değişiklikleri bir versiyon kontrol sistemi gibi yönetmenizi sağlar.

Migrasyon sırasında veri kaybı olur mu?

Doğru kullanıldığında olmaz. Ancak sütun tipi değiştirme gibi işlemlerde dikkatli olunmalıdır. Her zaman üretim ortamında işlem yapmadan önce yedeğinizi alın.

Autogenerate her değişikliği algılar mı?

Çoğu değişikliği algılar ancak bazen özel kısıtlamalar veya karmaşık veri tipi değişimlerinde manuel olarak migrasyon dosyasını düzenlemeniz gerekebilir.

Birden fazla geliştirici aynı anda çalışırken ne yapmalı?

Alembic, her migrasyon dosyasına benzersiz bir ID verir. Geliştiriciler kendi migrasyonlarını oluşturur ve ana depoya (repository) gönderir. Çakışmalar, standart Git süreçleriyle çözülür.

Downgrade işlemi neden başarısız olur?

Genellikle veritabanında o anki işlemle çakışan kısıtlamalar (constraints) veya silinen veriler nedeniyle olabilir. Migrasyon dosyalarınızı her zaman test ortamında deneyin.

İleri Seviye Migrasyon Senaryoları: Veri Taşıma ve Dönüştürme

Bazen şema değişikliği yapmak yeterli olmaz; mevcut verilerin yeni yapıya uyumlu hale getirilmesi (data migration) gerekir. Örneğin, bir User tablosundaki name ve surname sütunlarını birleştirip tek bir full_name sütununa dönüştürmek istediğinizde, Alembic'in op.execute() metodunu kullanmanız gerekir.

Aşağıdaki örnek, veritabanı seviyesinde veri dönüşümü yapmanın güvenli yolunu göstermektedir:

from alembic import op
import sqlalchemy as sa

def upgrade():
    # 1. Yeni sütunu ekle
    op.add_column('users', sa.Column('full_name', sa.String(100)))
    
    # 2. Mevcut verileri birleştirerek taşı
    op.execute("UPDATE users SET full_name = name || ' ' || surname")
    
    # 3. Eski sütunları kaldır
    op.drop_column('users', 'name')
    op.drop_column('users', 'surname')

def downgrade():
    # Geri dönüş senaryosunda sütunları tekrar oluştur ve veriyi böl
    op.add_column('users', sa.Column('name', sa.String(50)))
    op.add_column('users', sa.Column('surname', sa.String(50)))
    op.execute("UPDATE users SET name = split_part(full_name, ' ', 1), surname = split_part(full_name, ' ', 2)")
    op.drop_column('users', 'full_name')

Migrasyon Süreçlerinde Hata Ayıklama ve Performans İpuçları

Büyük ölçekli veritabanlarında migrasyonlar, tablo kilitleme (table locking) nedeniyle uygulama kesintilerine yol açabilir. Performansı korumak ve hata ayıklamayı kolaylaştırmak için şu stratejileri izlemelisiniz:

  • Batch Operations: Çok büyük tablolarda sütun eklerken veya indeks oluştururken batch_alter_table kullanarak veritabanı üzerindeki yükü optimize edin.
  • SQL Loglama: Migrasyon sırasında tam olarak hangi SQL komutlarının çalıştırıldığını görmek için alembic.ini dosyasında log seviyesini DEBUG olarak ayarlayın.
  • İndeks Yönetimi: Çok büyük tablolara indeks eklerken CONCURRENTLY (PostgreSQL için) seçeneğini kullanmayı düşünün. Bu, tablonun kilitlenmesini önler.

Aşağıda, batch_alter_table kullanarak güvenli bir sütun güncelleme örneği yer almaktadır:

def upgrade():
    with op.batch_alter_table('orders') as batch_op:
        batch_op.add_column(sa.Column('status', sa.String(20), server_default='pending'))
        batch_op.create_index('idx_order_status', ['status'])

def downgrade():
    with op.batch_alter_table('orders') as batch_op:
        batch_op.drop_index('idx_order_status')
        batch_op.drop_column('status')
Profesyonel İpucu: Üretim ortamında migrasyon çalıştırmadan önce, veritabanınızın bir yedeğini almayı ve migrasyonu önce bir "staging" ortamında simüle etmeyi asla ihmal etmeyin. alembic current komutu ile veritabanınızın hangi versiyonda olduğunu her zaman kontrol edebilirsiniz.

Sonuç

Bu rehberde, Python ile SQLAlchemy kullanarak veritabanı migrasyonu yapmanın temel adımlarını öğrendiniz. Alembic ile şema değişikliklerini yönetmek, projenizin sürdürülebilirliğini ve güvenliğini artırır. Bir sonraki adım olarak, karmaşık veritabanı ilişkilerini (Relationship) migrasyon dosyalarında nasıl yöneteceğinizi ve veritabanı indekslerini (Index) nasıl optimize edeceğinizi araştırmanızı öneririm. Profesyonel yazılım geliştirme süreçlerinde, migrasyonlarınızı her zaman bir CI/CD hattına entegre ederek otomatikleştirmeniz, hata oranını minimize edecektir.

Bu yazıya tepkinizi paylaşın:
Zeynep Kaya

Ev ekonomisi ve kişisel organizasyon üzerine birçok yayın yönettim. Okuyucuların günlük yaşam kalitesini artıracak uygulanabilir çözümler üretmeyi hedefliyorum.

Yorumlar (0)

Yorum Yaz