Flask Tutorial Database Operations

4-FlaskDatabase

Database Operations (Veritabanı işlemleri)

  • Flask aslen veritabanlarını desteklemez. Bunun pozitif yönü; Flask'i, kuracağınız üçüncü parti yazılımla istediğiniz database yaklaşımı veya tipi ile kullanabilirsiniz. İlişkisel(Relational) veya ilişkisel olmayan(non-Relational), SQL veya NoSQL database sistemleri için yazılmış extension'ları Flask'a entegre edip kullanabilirsiniz.
  • Burada biz ORM (Object Relational Mapping) kullanacağız. Bunun için uygun extension da Flask-SQLAlchemydir.
  • ORM sayesinde Python'da tanımladığımız modeller veritabanında tablolara karşılık gelecek.
  • pip install Flask-SQLAlchemy diyerek ihtiyacımız olan extension'ı kuruyoruz.
  • Biz SQLite veritabanını kullanacağız. SQLite hızlı, hafif, server kurulumu gerektirmeyen bir veritabanıdır.
  • Ayrıca pip install flask-migrate diyerek Flask-Migrate extension'ını kuruyoruz. Bu extension bize Python tarafında modelde değişiklik yaptığımızda, mevcut veritabanını bozmadan, silmeden güncelleme imkanı verecek. Burada tablolar arası ilişkinin güncellenmesi, alanların eklenmesi-silinmesi gibi işlemlerin gerçekleşmesinden söz ediyoruz.

config.py dosyamız üzerinde bir kaç işlem yapacağız.

 
  • Varsayılan olarak DATABASE_URL tanımlı ise onun değerini alacak, tanımlı değilse projemizin ana dizininde duracak şekilde blog.db'ye kaydolacak şekilde yerini ayarladık.
  • SQLALCHEMY_TRACK_MODIFICATIONS, database'de her değişiklik için bir sinyal belirten bu değeri False yaparak, iptal etmiş oluyoruz.
  • myapp/__init__.py dosyasında bir kaç değişiklik yapalım.
 
  • db değişkeni SQLAlchemy sınıfından oluşturulan nesne referansıdır.
  • Migrate() sınıfı app ve db değişkenlerini alarak, migration için bir nevi bağlantı yapıyor.

Şimdi myapp/models.py dosyamız ile User modelimizi belirleyelim.

 
  • User sınıfımız db.Model'i extend ediyor.
  • db.Column() parametre olarak alan tipini alır. Integer, String ..gibi. Extra parametreler indexleme ve unique olarak belirlenmesi için verilebilir.
  • id alanımız integer ve primary_key olacak.
  • username ve email String() sınıfı yardımı ile veritabanında verilen uzunluk kadar yerini alacak.
  • __repr__() methodu, debugging için ve objeleri nasıl yazacağını göstermek için kullanıyoruz.
  • Daha önce de söylediğimiz gibi modellerdeki değişimden sonra veritabanındaki tabloların değişmesi, silinmesi vb. durumlar için flask migrate ile database tekrar baştan oluşturulmadan, istenilen değişiklikler gerçekleştirilebiliyor.

Terminal'den:

 
  • Yukarıdaki komutları verdikten sonra projemize migrations adında bir klasör eklenecek.
 

Üstteki komut ile de tanımladığımız User modelini database'e tablo olarak yerleştirmek için hazırlıyoruz. Yani flask migrate bizim için script üretiyor.

  • Modelimizi database'e yazmak için flask db upgrade komutunu veriyoruz.
 
  • Proje dizinimize blog.db dosyası da eklendi. Ancak MySQL veya PostgreSQL gibi veri tabanları ile çalışıyorsanız serverda veri tabanını sizin oluşturmanız gerekiyor.
  • Flask-SQLAlchemy Tablo isimlerinde snake_case yapısını kullanıyor. Örneğin; User, veritabanında user olarak, AddressPhone ise address_phone olarak duruyor.
  • Eğer elle isim vermek isiyorsanız, __tablename__ kullanabilirsiniz. Örnek kullanım: __tablename__ = 'tablo_adi'
  • Eğer flask migrate ile üretilen scripti silmek/geri almak istiyorsanız flask db downgrade diyebilirsiniz.

Database relationships (Veritabanı ilişkileri)

db-relation

  • Projemiz için 1(one) kullanıcı(user) 1'den fazla(many) yayın(posts) yapacak şekilde One-To-Many ilişkisini yapacağız.
  • myapp/models.py modülümüzü düzenleyelim:
 
  • User modeline ilişkiyi eklememiz gerekiyor. db.relationship( ) ilk parametresi ilişki kurulacak sınıfın adı.
  • Post modelinde user_id referansına user.id foreign key olarak verildi ve User modeline bağlandı.
  • Post modelinde default=datetime.utcnow parametresi varsayılan olarak verildi. Ayrıca utcnow() yerine utcnow atandı. Yani sonuç yerine referans atandı. UTC ile kullanıcının bulunduğu bölgeye göre tarih, zaman bilgisini alıyoruz. Böylece farklı bölgelerdeki kullanıcılar için doğru zaman bilgisini garantiye almış oluyoruz.
  • db.relationship() ilk parametre olarak ilişki kurulacak sınıfın adını uppercase olarak alır.
  • db.Foreignkey() ise veritabanındaki tablo adı ve ilişki kurulacak alan adını lowercase olarak alır. Birden fazla kelime için snake_case kullanılır.
  • backref='author'; backref, many tarafındaki posts'lar için veritabanı ilişkisindeki one tarafını temsil eder.posts.author diyerek verilen post için kullanıcısına erişebiliriz.
  • lazy parametresi veritabanı ilişkisinin nasıl kurulacağını belirtiyor.

Şimdi terminalden migration işlemini yapalım.

 
  • Şimdi python shell'i açıp bir kaç database işlemi yapalım.
 
  • Database objemizi (db) ve modellerimizi (User, Post) import ettik.
  • Yeni bir User objesi oluşturduk ve username ile email alanlarına atama yaptık.
  • Değişiklikleri veritabanına uygulamak için db.session contextini kullanıyoruz. Yeni User nesnesinin u referansını db.session.add(u) diyerek database'e yazılabilir hale getirdik. Son olarak db.session.commit() diyerek değişiklikleri veritabanına uyguladık.
  • db.session.rollback(), herhangi bir zamanda bir sessionda hata oluştuğunda, kaydedilmiş değişiklikleri iptal eder.
  • Bir kayıt daha ekleyelim veritabanımıza.
 
  • Her model query attribute'e sahiptir. dir(User.query) yazarsnız python shell'de iken, kullanabileceğiniz attribute listesini görebilirsiniz.
  • SQL'deki gibi select * from tablo_adi sorgusu yerine .all() methodu ile modele ait bütün kayıtlar geliyor.
  • Eğer id'sini biliğiniz bir kayıt getirmek istiyorsanız. .get(id) ile kaydı alabilirsiniz.
 
  • User modelinde tanımladığımız db.releationship() users & posts ilişkisini sağlar. backref parametresine atadığımız author alanı da user ID'leri yerine kullanıldı. Burada author, User sınıfının bir objesini temsil eder.
  • Kayıtlarımızı sıralı bir şekilde getirmek için order_by kullandık.
Kayıt Silmek (Deleting Record)
 
  • Kayıtları silmek için db.session.delete(kayit_adi) kullanıyoruz.
Flask Shell
  • Python shell yerine flask shell kullanmayı görelim.
 
  • Herhangi bir import yapmadan flask varsayılan olarak uygulama örneğini (application instance) dahil ediyor.
  • Shell test yaparken çok kullanılan ortamlardan biridir.

blog/main.py modülümüzü düzenleyelim.

 
  • @app.shell_context_processor methodumuzu shell context fonksiyonu haline getirir. flask shell komutu çalıştığı zaman tanımladığımız değerler otomatik olarak import edilmiş olur.

$ flask shell komutunu terminalden çalıştıralım.

 
  • @app.shell_context_processor ekledikten sonra sürekli import etmemize gerek kalmadan istediğimiz modele, modüle erişebiliriz.

 

 

 

Yorumlar