- Katılım
- 7 Nis 2025
- Konular
- 367
- Mesajlar
- 780
- Çözümler
- 1
- Tepkime puanı
- 121
- Puan
- 93
- Konum
- İstanbul
- Web sitesi
- forumagel.com
Hazır Kod Bankası - Konu 21: Python Flask ile Veritabanı (SQLAlchemy) Entegrasyonu Temelleri
Hazır Kod Bankası Serimizin Yirmi Birinci Konusu: Flask ile Veritabanı Entegrasyonu!
Merhaba arkadaşlar! Flask ile temel web uygulamaları geliştirmeyi öğrendik. Ancak dinamik web siteleri, kullanıcı etkileşimlerinden gelen veriyi (kayıtlar, yorumlar, ürünler vb.) kalıcı olarak saklamak ve gerektiğinde bu verilere hızlıca erişmek zorundadır. İşte bu yüzden web uygulamalarını bir veritabanına bağlamak kritik öneme sahiptir.
Bu konuda, Python dünyasında çok popüler olan SQLAlchemy ORM'ini, Flask ile entegrasyonunu sağlayan Flask-SQLAlchemy uzantısı aracılığıyla kullanarak Flask uygulamamızı bir veritabanına bağlamayı ve temel veri işlemleri olan Ekleme (Create), Okuma (Read), Güncelleme (Update) ve Silme (Delete) yani CRUD operasyonlarını nasıl yapacağımızı öğreneceğiz.
ORM (Object-Relational Mapper - Nesne İlişkisel Eşleyici), veritabanı tablolarını programlama dilinizdeki sınıflara (Python'da Class), tablodaki her bir satırı bu sınıfların nesnelerine (Object) ve tablonun sütunlarını da nesnelerin özelliklerine (Attribute) eşleyen bir araçtır. Bu sayede veritabanı işlemlerini SQL sorguları yazmak yerine, sanki Python nesneleriyle çalışır gibi yapabilirsiniz. Bu da kodunuzu daha anlaşılır ve bakımını kolay hale getirir.
Ön Gereksinim:
- Python ve Flask kurulu olmalı (Konu 9 ve Konu 20).
- Flask-SQLAlchemy uzantısı kurulu olmalı: `pip install Flask-SQLAlchemy`
- Bir veritabanı sunucusu çalışıyor olmalı. Örneklerimizde ek kurulum gerektirmeyen ve dosya tabanlı çalışan SQLite kullanacağız.
1. Flask Uygulamasını Veritabanına Bağlama
Flask uygulamamızı bir veritabanına bağlamak için `app.config` objesini kullanırız. `SQLALCHEMY_DATABASE_URI` ayarı, hangi veritabanına bağlanılacağını belirtir. SQLite için dosya yolunu belirtmek yeterlidir.
Python:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy # Flask-SQLAlchemy sınıfını içe aktar
import os # Dosya yolları için 'os' modülünü içe aktar
app = Flask(__name__)
# Veritabanı dosyasının yolu (uygulama dosyasının olduğu klasörde 'site.db' adında)
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'site.db')
# Modifikasyon izlemeyi kapatmak (genellikle gereksizdir ve performansı etkileyebilir)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# SQLAlchemy nesnesini oluştur
db = SQLAlchemy(app)
# Uygulama çalıştırma kısmı (opsiyonel, genellikle dosyanın sonunda yer alır)
# if __name__ == '__main__':
# app.run(debug=True)
2. Model Tanımlama (Tablodan Sınıfa Eşleme)
Veritabanındaki tabloları Python sınıflarına eşlemek için `db.Model` sınıfından miras alan sınıflar tanımlarız. Tablonun sütunları, bu sınıfların özellikleri (class attributes) olarak `db.Column` kullanılarak tanımlanır.
Python:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import os
# from datetime import datetime # Eğer tarih/saat alanı kullanacaksanız içe aktar
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'site.db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# Kullanıcı tablosunu temsil eden Model sınıfı
class User(db.Model):
# Tablonun sütunları (özellikleri)
id = db.Column(db.Integer, primary_key=True) # INTEGER PRIMARY KEY otomatik artar
username = db.Column(db.String(20), unique=True, nullable=False) # VARCHAR(20), benzersiz, boş olamaz
email = db.Column(db.String(120), unique=True, nullable=False) # VARCHAR(120), benzersiz, boş olamaz
# image_file = db.Column(db.String(20), nullable=False, default='default.jpg') # Örnek sütun
# password = db.Column(db.String(60), nullable=False) # Örnek şifre sütunu
# posts = db.relationship('Post', backref='author', lazy=True) # Başka bir tabloyla ilişki (İleri konu)
# kayit_tarihi = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) # Örnek tarih sütunu
# Nesne yazdığında nasıl görüneceğini belirleyen özel metot (Opsiyonel)
def __repr__(self):
return f"User('{self.username}', '{self.email}')"
# Eğer Post gibi başka modelleriniz varsa buraya eklersiniz
# class Post(db.Model):
# id = db.Column(db.Integer, primary_key=True)
# title = db.Column(db.String(100), nullable=False)
# date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
# content = db.Column(db.Text, nullable=False)
# user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) # User tablosuna foreign key
# Uygulama çalıştırma kısmı ...
# if __name__ == '__main__':
# app.run(debug=True)
3. Veritabanı Tablolarını Oluşturma
Modellerinizi tanımladıktan sonra, bu modellere karşılık gelen veritabanı tablolarını oluşturmanız gerekir. Bu işlem genellikle bir kere yapılır veya modellerinizde değişiklik yaptığınızda (bu değişiklikleri veritabanına yansıtmak için "migration" araçları kullanılır, ileri konu) tekrarlanır.
Tabloları oluşturmak için Python kabuğunu (shell) veya uygulamanızın içinde kısa bir betik kullanabilirsiniz. Uygulama bağlamı (application context) içinde olmanız önemlidir.
Python:
# Bu kodu ana Flask uygulamanızın (app.py) altına ekleyin veya ayrı bir betik olarak çalıştırın
# Ayrı betik olarak çalıştıracaksanız app ve db objelerinin tanımlı olduğundan emin olun.
# Örnek olarak app.py dosyasının sonunda main bloğundan önce veya sonra çalıştırılabilir:
# from app import app, db # Eğer ayrı bir dosyadan çalıştırıyorsanız bu satırı ekleyin
with app.app_context(): # Uygulama bağlamına gir
db.create_all() # Tanımlanmış tüm modeller için veritabanı tablolarını oluştur
print("Veritabanı tabloları oluşturuldu!")
# Artık uygulamayı app.run() ile normal şekilde çalıştırabilirsiniz.
# Eğer bu kodu app.py içine koyduysanız ve app.run() sonrası değilse, çalıştırıldığında tabloları oluşturur.
# main bloğu içine koymak en yaygın yoldur:
# if __name__ == '__main__':
# with app.app_context():
# db.create_all() # Uygulama her çalıştığında tabloları oluşturur (mevcutsa tekrar oluşturmaz)
# app.run(debug=True)
4. Temel CRUD İşlemleri (ORM ile)[/B]
Tabloları oluşturduktan sonra, Flask-SQLAlchemy ve tanımladığınız modeller aracılığıyla veritabanına veri ekleme, okuma, güncelleme ve silme (CRUD) işlemlerini yapabilirsiniz. Bu işlemler için `db.session` objesi kullanılır.
- Create (Ekleme):
Python:# Yeni bir kullanıcı nesnesi oluştur yeni_kullanici = User(username='HazirKodBankasi', email='[email protected]') # Nesneyi session'a ekle (veritabanına eklenmek üzere sıraya al) db.session.add(yeni_kullanici) # Değişiklikleri veritabanına kaydet (commit) db.session.commit() print("Yeni kullanıcı eklendi!")
- Read (Okuma/Sorgulama): Veritabanından veri çekmek için model sınıfının `.query` özelliğini kullanırız.
Python:# Tüm kullanıcıları getir (Liste olarak döner) all_users = User.query.all() print("Tüm Kullanıcılar:", all_users) # __repr__ metodu sayesinde okunabilir çıktı # ID'si 1 olan kullanıcıyı getir (Tek nesne veya None döner) user_by_id = User.query.get(1) if user_by_id: print("ID'si 1 olan kullanıcı:", user_by_id) else: print("ID 1 bulunamadı.") # username'i 'HazirKodBankasi' olan kullanıcıyı filtrele (Sorgu objesi döner) user_by_username = User.query.filter_by(username='HazirKodBankasi').first() # first() ilk eşleşeni getirir if user_by_username: print("Username HKB olan:", user_by_username) # Email adresi '@example.com' ile biten kullanıcıları getir (Birden fazla olabilir) # filter() daha esnek sorgular için kullanılır # from sqlalchemy import like # Eğer like operatoru kullanacaksaniz # users_by_email_end = User.query.filter(User.email.like('%@example.com')).all()
- Update (Güncelleme): Güncellenecek nesneyi sorgu ile bulur, özelliklerini değiştirir ve commit ederiz.
Python:# Email adresini güncellemek istediğimiz kullanıcıyı bulalım (ID'si 1 olsun) user_to_update = User.query.get(1) # Veya filter_by ile bulabilirsiniz if user_to_update: user_to_update.email = '[email protected]' # Özelliği değiştir db.session.commit() # Değişikliği veritabanına kaydet print(f"Kullanıcı {user_to_update.username} email güncellendi.") else: print("Güncellenecek kullanıcı bulunamadı.")
- Delete (Silme): Silinecek nesneyi bulur, session'dan siler ve commit ederiz.
Python:# Silmek istediğimiz kullanıcıyı bulalım (Username'i 'HazirKodBankasi' olsun) user_to_delete = User.query.filter_by(username='HazirKodBankasi').first() if user_to_delete: db.session.delete(user_to_delete) # Nesneyi session'dan sil db.session.commit() # Değişikliği veritabanına kaydet print(f"Kullanıcı {user_to_delete.username} silindi.") else: print("Silinecek kullanıcı bulunamadı.")
5. Flask Route'ları İçinde CRUD İşlemleri ve Şablonda Gösterme[/B]
SQLAlchemy kullanarak veritabanı işlemlerini nasıl yapacağımızı öğrendik. Şimdi bunları Flask route'larımız içine yerleştirerek web arayüzü üzerinden kullanıcının veritabanıyla etkileşimini sağlayabiliriz.
Python:
from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
import os
# from datetime import datetime # Eğer tarih kullanıyorsanız
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'site.db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# !!! Model tanımı buraya gelecek (Yukarıdaki User sınıfı gibi) !!!
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return f"User('{self.username}', '{self.email}')"
# !!! Model tanımı bitti !!!
# Veritabanı tablolarını oluştur (Genellikle sadece ilk çalıştırmada veya model değiştiğinde yapılır)
# Uygulama başlatılırken tablo oluşturmak için:
with app.app_context():
db.create_all()
print("Veritabanı tabloları kontrol edildi/oluşturuldu.")
# Anasayfa (Kullanıcıları Listele)
@app.route('/')
def index():
users = User.query.all() # Tüm kullanıcıları veritabanından çek
return render_template('users.html', users=users) # Kullanıcı listesini şablona gönder
# Yeni Kullanıcı Ekle (Form hem GET hem POST)
@app.route('/add_user', methods=['GET', 'POST'])
def add_user():
if request.method == 'POST':
# Formdan verileri al
username = request.form.get('username') # .get() metodu hata vermez, None döndürür
email = request.form.get('email')
# Basit doğrulama
if username and email:
# Yeni User nesnesi oluştur
new_user = User(username=username, email=email)
# Session'a ekle ve veritabanına kaydet
db.session.add(new_user)
db.session.commit()
# Kullanıcı ekledikten sonra listeleme sayfasına yönlendir
return redirect(url_for('index'))
else:
# Hata mesajı ile formu tekrar göster (Opsiyonel, şablonda gösterilebilir)
return render_template('add_user.html', error="Kullanıcı adı ve E-posta boş olamaz!")
# GET isteği ise sadece formu göster
return render_template('add_user.html')
# Kullanıcı Güncelle (Çok basit örnek, ID ile)
@app.route('/update_user/<int:user_id>', methods=['GET', 'POST'])
def update_user(user_id):
user_to_update = User.query.get_or_404(user_id) # Kullanıcıyı bul veya 404 hatası ver
if request.method == 'POST':
user_to_update.username = request.form.get('username')
user_to_update.email = request.form.get('email')
db.session.commit()
return redirect(url_for('index'))
# GET isteği ise formu mevcut bilgilerle doldurarak göster
return render_template('update_user.html', user=user_to_update)
# Kullanıcı Sil (Çok basit örnek, ID ile ve GET isteği ile)
# Genellikle DELETE metodu veya form kullanılır, bu sadece örnek
@app.route('/delete_user/<int:user_id>', methods=['POST']) # Sadece POST isteklerini kabul et
def delete_user(user_id):
user_to_delete = User.query.get_or_404(user_id)
db.session.delete(user_to_delete)
db.session.commit()
return redirect(url_for('index')) # Silme sonrası listeye dön
if __name__ == '__main__':
app.run(debug=True)
Şimdi templates klasörüne gerekli HTML dosyalarını ekleyin:
[CODE=html]
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>Kullanıcı Listesi</title><style> table, th, td { border: 1px solid black; border-collapse: collapse; padding: 8px; }</style></head><body><h1>Kullanıcılar</h1><p><a href="{{ url_for('add_user') }}">Yeni Kullanıcı Ekle</a></p>
<table><br> <thead><br> <tr><br> <th>ID</th><br> <th>Kullanıcı Adı</th><br> <th>E-posta</th><br> <th>İşlemler</th> {# Yeni sütun #}<br> </tr><br> </thead><br> <tbody><br> {# Flask'tan gelen 'users' listesi üzerinde döngü #}<br> {% for user in users %}<br> <tr><br> <td>{{ user.id }}</td><br> <td>{{ user.username }}</td><br> <td>{{ user.email }}</td><br> <td><br> <a href="{{ url_for('update_user', user_id=user.id) }}">Güncelle</a><br> |<br> {# Silme işlemi için basit form (GET yerine POST önerilir) #}<br> <form action="{{ url_for('delete_user', user_id=user.id) }}" method="POST" style="display:inline;"><br> <input type="submit" value="Sil" onclick="return confirm('Bu kullanıcıyı silmek istediğinizden emin misiniz?');"><br> </form><br> </td><br> </tr><br> {% endfor %}<br> </tbody><br></table><br>
</body></html>
HTML:
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>Kullanıcı Ekle</title></head><body><h1>Yeni Kullanıcı Ekle</h1>
{# Flask'tan hata değişkeni geldiyse göster #}<br>{% if error %}<br> <p style="color:red;">{{ error }}</p><br>{% endif %}<br><br><form action="" method="POST"> {# action="" aynı route'a POST eder #}<br> <label for="username">Kullanıcı Adı:</label><br><br> <input type="text" id="username" name="username" required><br><br><br><br> <label for="email">E-posta:</label><br><br> <input type="email" id="email" name="email" required><br><br><br><br> <input type="submit" value="Ekle"><br></form><br><br><p><a href="{{ url_for('index') }}">Kullanıcı Listesine Dön</a></p><br>
</body></html>
HTML:
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>Kullanıcı Güncelle</title></head><body><h1>Kullanıcı Güncelle</h1>
<form action="" method="POST"> {# action="" aynı route'a POST eder #}<br> <label for="username">Kullanıcı Adı:</label><br><br> {# Mevcut bilgiyi input içine yerleştir #}<br> <input type="text" id="username" name="username" value="{{ user.username }}" required><br><br><br><br> <label for="email">E-posta:</label><br><br> {# Mevcut bilgiyi input içine yerleştir #}<br> <input type="email" id="email" name="email" value="{{ user.email }}" required><br><br><br><br> <input type="submit" value="Güncelle"><br></form><br><br><p><a href="{{ url_for('index') }}">Kullanıcı Listesine Dön</a></p><br>
</body></html>
Sıra Sizde![/B]
Flask-SQLAlchemy ile Flask uygulamamızı veritabanına bağladık ve temel CRUD işlemlerini web arayüzü üzerinden yapacak bir örnek oluşturduk.
- [] Flask-SQLAlchemy'yi kurdunuz mu (pip install Flask-SQLAlchemy)?[] Uygulamanızın veritabanı URI ayarını yaptınız mı (app.config['SQLALCHEMY_DATABASE_URI'])? SQLite kullanmak en kolayı olacaktır.[] Kendi User modelinizi veya başka bir model (örneğin Product modeli) tanımladınız mı?[] with app.app_context(): db.create_all() kodunu çalıştırarak veritabanı tablolarını oluşturdunuz mu? (İlk çalıştırmada site.db dosyası oluşmalı).[] Kullanıcı ekleme formunu (add_user.html), listeleme sayfasını (users.html) ve güncelleme sayfasını (update_user.html) şablon klasörünüze koydunuz mu?[] Flask route'larını (index, add_user, update_user, delete_user) ve içlerindeki CRUD mantığını incelediniz mi?[] Uygulamayı çalıştırıp tarayıcıdan kullanıcı ekleme, listeleme, güncelleme ve silme işlemlerini test ettiniz mi?[] Ekleme formunda boş alan bırakarak basit doğrulamayı denediniz mi?
Serinin Geleceği?[/B]
Flask ile veritabanı entegrasyonunun temellerini (CRUD) gördük. Bu, dinamik web uygulamaları için çok önemli bir adımdır.
Seriyi buradan sonra nasıl devam ettirelim?
- [] Flask-SQLAlchemy'de daha ileri konular (Tablolar arası ilişkiler - Relationships, Migration araçları - Alembic)?[] Flask'ın diğer uzantıları ve özellikleri (WTForms ile form yönetimi, Blueprints ile modüler yapı, kullanıcı oturumları)?[] Diğer popüler Python Web Framework'lerine giriş (Django Temelleri)?[] JavaScript Frameworklerine giriş (React, Vue, Angular)?[] Java Web Frameworklerine giriş (Spring Boot Temelleri)?[] Web API (REST API) yapımı temelleri (Flask-RESTful/RESTX, Django Rest Framework, Node.js Express)?[] Daha ileri Veri Yapıları ve Algoritma konuları (Bağlı Listeler, Ağaçlar, Grafikler)?[] Başka bir programlama diline giriş (C#, C++ gibi)?[] Mobil geliştirme temelleri?[] Veya başka önerileriniz mi var?
Umarım bu konu, Python bilginizi kullanarak veritabanı destekli web uygulamaları geliştirmeye başlarken faydalı olmuştur. Görüşmek üzere!
Anahtar Kelimeler: Flask veritabanı, Flask database, Flask SQLAlchemy, Python ORM, Flask DB entegrasyonu, Flask veri ekleme, Flask veri okuma, Flask CRUD, Flask model tanımlama, Flask db.Model, Flask db.Column, Flask db.session, Flask query all, Flask query filter_by, Flask veri güncelleme, Flask veri silme, Flask SQLite, Flask MySQL, Python web database, Flask web projesi database, Flask ORM dersleri, Flask veritabanı örneği, Flask web app with db, Flask-SQLAlchemy kurulumu, ORM nedir, Flask ile SQLite, Python ile CRUD, Flask web form database, Flask ile liste yapma, Flask ile kullanıcı ekleme.
Bu konu, "Hazır Kod Bankası" serisinin yirmi birinci parçasıdır ve "Yazılım Bilgi ve Yeni Başlayanlar İçin" kategorisi altında paylaşılmıştır.
<br>Bu taslak, serinin yirmi birinci konusu olarak forumunuzda yayınlanmaya hazır. Python Flask ile SQLAlchemy kullanarak veritabanı entegrasyonunun ve temel CRUD işlemlerinin temellerini anlatıyor. İstenen `
Python:
` ve `[CODE=html]` formatları ile anahtar kelimeler eklenmiştir. Başlık ve alt başlıklardaki `[SIZE=X][B]...[/B][/SIZE]` yapılarını kontrol ederek hatalı kullanımları düzelttim.<br><br>Serinin bir sonraki konusu hakkında önerilerinizi bekliyorum. Hazırsanız ve bir önerini