ORM Nedir ve SQLAlchemy Kullanımı

ORM; Object Relational Mapper tanımının baş harfleriyle oluşan bu kısaltma, ilişkisel bir veritabanı(MySql, Sqlite …) ile programımız arasında alışverişi yaparak bize zaman kazandıran bir kütüphanelere verilen isimdir.

Normal bir süreçte veritabanı oluşturulur, Python ile bu veritabanına bağlanılır ve bir sorgu(query) hazırlanarak bu bağlantı üzerinden gönderilir dönen cevap işlenir ve kullanılır.

Bir ORM kütüphanesi kullandığımızda ise veritabanında oluşturacağımız tabloların düzenine uygun olarak sınıflar oluştururuz. Ve sınıflardan nesneler oluşturarak, sorgu göndermek yerine bu nesneleri kullanırız. Kısacası sorgu yazmak yerine Python kodu yazarak hayatımızı kolaylaştırıyoruz. Hem daha hızlı geliştirilebilen hem de daha güvenli bir programımız oluyor.

Eksi yanları ise; Impedance Mismatch denilen nesne ve ilişkisel veritabanı arasındaki olası farklılıklar, performans sorunları ve karmaşık veritabanlarında kullanım zorluğu olabilir.

En çok bilinen ORM kütüphaneleri Django’ya ait olan Django’s ORM ve SQLAlchemy. Mantıkları benzer olduğu için hangisinin kullanılması gerektiği detayına girmeden SQLAlchemy ile bir kaç örnek yapalım.

Öncelikle kurulum için en kolay yol olan “pip install sqlalchemy” komutunu komut satırına yazıyoruz. Kurulum tamamlandıktan sonra kullanıma başlayabiliriz.

Bir okul için yönetim sistemi yaptığımızı düşünerek öğretmen ve ders tablolarımız ve ilişkilerini tasarlamamız gerektiğini varsayalım. Öncelikle bu tabloları oluşturmak için bazı komutlar yazmamız gerekiyordu fakat ORM tabanında SQL kodu yapmayacağız dedik. Bunun yerine tanımladığımız sınıfları bildirmemiz gerekli. Aşağıda şekilde dosyamızı decleration.py ismiyle kaydedelim.

from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import create_engine

Base = declarative_base()

class Ogretmen(Base):
    __tablename__ = 'ogretmen'

    id = Column(Integer, primary_key=True)
    isim = Column(String(250), nullable=False)

class Ders(Base):
    __tablename__ = 'ders'

    id = Column(Integer, primary_key=True)
    isim = Column(String(250), nullable=False)
    ogretmen_id = Column(Integer, ForeignKey('ogretmen.id'))
    ogretmen = relationship(Ogretmen, backref='ders')


# sqlite olarak kayıtedilecek dosyayı gösteriyoruz
engine = create_engine('sqlite:///okul_sistemi.db')

# Tanımladığımız Base üzerindeki tabloları oluşturuyoruz
Base.metadata.create_all(engine)

Programımızda Ogretmen ve Ders adında Base sınıfı üzerine iki sınıf oluşturuyoruz. Bu sınıflar tablolarımız oluyor aslında. Aralarındaki ilişkiyi ise Ders sınıfında kullandığımız ForeignKey ve relationship fonksiyonları ile sağlıyoruz. Dosyamızı kaydedik çalıştırdıktan sonra bir okul_sistemi.db dosyası oluşması gerekli klasörümüzde. Bu bizim SQLite veritabanımız.

Veritabanı hazır şimdi bazı kayıtlar oluşturalım. Aşağıdaki kodları insert.py olarak kaydedip çalıştırarak 2 öğretmen ve 4 ders oluşturabiliriz.

from declaration import Ogretmen, Ders, Base

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine('sqlite:///okul_sistemi.db')
Base.metadata.bind = engine

DBSession = sessionmaker(bind=engine)
session = DBSession()

hasan = Ogretmen(isim='Hasan')
session.add(hasan)
ayse = Ogretmen(isim='Ayşe')
session.add(ayse)
session.commit()

tarih = Ders(isim='Tarih', ogretmen=hasan)
cografya = Ders(isim='Cografya', ogretmen=hasan)
biyoloji = Ders(isim='Biyoloji', ogretmen=ayse)
fizik = Ders(isim='Fizik', ogretmen=ayse)

session.add_all([tarih, cografya, biyoloji, fizik])
session.commit()

Kodlar gayet açık aslında tek yaptığımız önceki sınıflarımızı import edip bunlardan nesneler oluşturmak ve başlattığımız oturuma(session) bunları ekleyerek işlemek(commit). Bu dosyamızı da kaydedip çalıştırdıktan sonra sırada verilerimizi çekmeye geliyor. Bu dosyayı ne kadar çalıştırırsanız o kadar kayıt ekleyecektir. Bir kaç tane Hasan hoca kaydınız olursa bu yüzdendir.

from declaration import Ogretmen, Ders, Base

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine('sqlite:///okul_sistemi.db')
Base.metadata.bind = engine

DBSession = sessionmaker(bind=engine)
session = DBSession()

ogretmenler = session.query(Ogretmen).all()
print(["{} öğretmeni {} Hoca".format(ders.isim, ogretmen.isim) for ogretmen in ogretmenler for ders in ogretmen.ders])

hasan = session.query(Ogretmen).filter(Ogretmen.isim=='Hasan').first()
dersler = session.query(Ders).filter(Ders.ogretmen==hasan).all()
print("Hasan hocaya ait derler")
print([ders.isim for ders in dersler])

query.py adını verdiğimiz bu dosyayı da çalıştırdığımızda bize öğretmenlerin verdiği dersleri ve Hasan hocanın verdiği dersleri listeleyecektir.

Çıktı şu şekilde olmalı;

['Tarih öğretmeni Hasan Hoca',
 'Cografya öğretmeni Hasan Hoca', 
 'Biyoloji öğretmeni Ayşe Hoca',
 'Fizik öğretmeni Ayşe Hoca']
Hasan hocaya ait derler
['Tarih', 'Cografya']

Basit bir veritabanı için ideal oldu daha kompleks yapılar için de pek çok fonksiyonu var SQLAlchemy ve Django’s ORM’in.

Yararlandığım bazı kaynaklar;
http://blog.fatiherikli.com/post/django-orm-etkili-bir-sekilde-kullanmak/
https://tutorial.djangogirls.org/tr/django_orm/
http://www.halitalptekin.com/elixir-ve-sqlalchemy.html


Yayımlandı

kategorisi

yazarı:

Yorumlar

“ORM Nedir ve SQLAlchemy Kullanımı” için 3 cevap

  1. öğrenci sınıfı yok ama importta var, kafa karıştırabilir.

    1. Erdoğan

      Düzenlemeyi yaptım, teşekkürler.

  2. Ferid

    ogretmenler = session.query(Ogretmen).all()
    print([“{} öğretmeni {} Hoca”.format(ders.isim, ogretmen.isim) for ogretmen in ogretmenler for ders in ogretmen.ders])

    kısmında en sonda ogretmen.ders nasıl ola biliyor?

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir