New version

This commit is contained in:
C ve Sistem Programcıları Derneği 2025-04-15 16:10:41 +03:00
parent 19cf9872de
commit 03ba1b5a2a
2 changed files with 362 additions and 234 deletions

BIN
.DS_Store vendored

Binary file not shown.

View file

@ -2182,7 +2182,7 @@ python -m timeit -n 100000 "'-'.join(str(i) for i in range(100))"
SELECT student_name, student_no FROM student_info WHERE student_no > 600;
Burada numarası 600'den büyükolan öğrencilerin isimleri ve numaraları elde edilmektedir. Sütun istesi yerine * kullanılırsa bu
Burada numarası 600'den büyük olan öğrencilerin isimleri ve numaraları elde edilmektedir. Sütun istesi yerine * kullanılırsa bu
durum "tüm sütunlar" anlamına gelmektedir. Örneğin:
SELECT * FROM student_info WHERE student_no > 600;
@ -2447,8 +2447,8 @@ python -m timeit -n 100000 "'-'.join(str(i) for i in range(100))"
#------------------------------------------------------------------------------------------------------------------------------------
SQL SELECT cümlesinin Python'da uygulanması üzerinde ayrıca durmak gerekir. Çünkü SELECT cümlesi ile biz VTYS'den kayıt çekmekteyiz.
SELECT cümlesi yine diğer cümlelerde olduğu gibi Cursor sınıfının execute metodu ile işletilir. Kayıtlar Cursor sınıfının fetchone
ve fetchmany isimli metotlarıyla elde edilmektedir. fetchone metodu koşulu sağlayan kayıtlardan yalnızca bir tanesini, fetchmany ise
n tanesini elde etmekte kullanılmaktadır. Tabii bu metotlar birden fazla kez çağrılabilirler. fetchone kaydı tek bir demet olarak
ve fetchmany isimli metotlarıyla elde edilmektedir. fetchone metodu koşulu sağlayan kayıtlardan yalnızca bir tanesini, fetchmany
ise n tanesini elde etmekte kullanılmaktadır. Tabii bu metotlar birden fazla kez çağrılabilirler. fetchone kaydı tek bir demet olarak
fetchmany ise kayıtları bir demet listesi olarak varmektedir. Demetlerin elemanları SELECT komutunda belirtilen sütun sıralarına
göredir.
@ -2601,7 +2601,7 @@ s
#------------------------------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------------------------------
10. Ders 06/04/2025 - Pazar
10. Ders 06/04/2025 - Pazar
#------------------------------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------------------------------
@ -2624,8 +2624,8 @@ s
#------------------------------------------------------------------------------------------------------------------------------------
INSERT, UPDATE, DELETE işlemleri sonucunda bu işlemlerden etkilenen kayıt sayısı Cursor sınıfının rowcount isimli örnek özniteliğinden
elde edilebilmektedir. Örneğin biz DELETE komutu ile bir grup kaydı silmişsek rowcount bize silinen kayıtların sayısını verir.
rowcount örnek özniteliği SELECT komutu uygulandığında set edilmemektedir. Yani biz SEELCT edilen satırların sayısını rowcount ile
elde edilebilmektedir. Örneğin biz DELETE komutu ile bir grup kaydı sildiğimizde rowcount bize silinen kayıtların sayısını verecektir.
rowcount örnek özniteliği SELECT komutu uygulandığında set edilmemektedir. Yani biz SELECT edilen satırların sayısını rowcount ile
elde edemeyiz.
Aşağıdaki örnekte biz veritabanına 1 kayıt insert ediyoruz. Dolayısıyla rowcount bize 1 değerini verecektir.
@ -2677,7 +2677,7 @@ except Exception as e:
bir öğrenciyi INSERT ederken school tablosunda olmayan bir school_id girmemeliyiz. Bu tür kontoller şüphesiz manuel biçimde school
tablosu sorgulanarak yapılabilir. Ancak VTYS'ler bu tür işlemleri kendi içlerinde yapabilmektedir. Bunlara "yabancı anahtar kısıtları
(foreign key constraints)" denilmektedir. Yabancı anahtar kısıtları tablo yaratılırken CREATE TABLE komutunda komutun sonunda belirtilmektedir.
VTYS'ler arasında bu konuda farklılıklar bulunmaktadır. Örneğin SQLite'ta CREATE TABLE komutunda komutunun sonunda aşağıaki gibi kısıt
VTYS'ler arasında bu konuda farklılıklar bulunmaktadır. Örneğin SQLite'ta CREATE TABLE komutunda komutun sonuna aşağıaki gibi kısıt
girilebilir:
CREATE TABLE student (
@ -2685,22 +2685,22 @@ except Exception as e:
FOREIGN KEY (school_id) REFERENCES school(school_id)
)
Burada student tablosunaki school_id sütunu scool tablosundaki school_id ütunu ile foreign key temelinde ilişkilendirilmiştir.
Burada student tablosunaki school_id sütunu school tablosundaki school_id sütunu ile "foreign key" temelinde ilişkilendirilmiştir.
Artık biz bir örenciyi eklerken school tablosunda olmayan bir scool_id girersek işlme başarısızlıkla sonuçlanacaktır.
#------------------------------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------------------------------
Bazı tablolarda bazı sütunlar "yabancı anahtar (foreign key)" durumundadır. Öğrenğin school tablosunun school_id elemanı hem PRIMARY KEY
durumundadır hem de student tablosu için FOREIGN KEY durumundadır. school tablosuna bir okul eklerken ekleyen kişinin school_id vermesi
zor bir kullanımdır. İşte bu tür durumlarda anımsanacağı gibi ilgili sütuna AUTOINCREMENT özelliği verilebilmektedir. AUTO INCREMENT
bir sütun söz konusu olduğunda eğer INSERT işleminde bu sütun belirtilmezse bu durumda VTYS en büyük numaranın bir fazlasını almaktadır.
SQLite'ta aslında PRIMARY KEY olan tamsayı alanları otomatik AUTOINCREMENT durumdadır. Ancak uygulamacı AUTOINCREMENT belirlemesini
yine yapabilir.
Bazı tablolarda bazı sütunlar "yabancı anahtar (foreign key)" durumundadır. Öğrenğin school tablosunun school_id elemanı hem
PRIMARY KEY durumundadır hem de student tablosu için FOREIGN KEY durumundadır. school tablosuna bir okul eklerken ekleyen kişinin
school_id vermesi zor bir kullanımdır. İşte bu tür durumlarda anımsanacağı gibi ilgili sütuna AUTOINCREMENT özelliği verilebilmektedir.
AUTOINCREMENT bir sütun söz konusu olduğunda eğer INSERT işleminde bu sütun belirtilmezse bu durumda VTYS en büyük numaranın bir
fazlasını almaktadır. SQLite'ta aslında PRIMARY KEY olan tamsayı alanları aynı zamanda AUTOINCREMENT durumdadır. Ancak uygulamacı
AUTOINCREMENT belirlemesini yine yapabilir.
#------------------------------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------------------------------
Bazen veritabanı üzerinde birbirleriyle ilişkili olan işlemler yapılıyor olabilir. Bu tür işlemlerin "ya hep ya hiç" biçiminde
gereçekleştirilmesi gerelebilmektedir. İşte VTYS'lerde "bir grup eylemin sanki tek bir eylemmiş gibi peşi sıra gerçekleştirilmesine
gereçekleştirilmesi gerelebilmektedir. İşte VTYS'lerde bir grup eylemin sanki tek bir eylemmiş gibi peşi sıra gerçekleştirilmesine
"transaction" denilmektedir. Örneğin bir grup bilginin birbirleriyle tutarlı bir biçimde üç farklı tabloya insert edilmek istendiğini
düşünelim. Biz bu üç insert işlemi başarılıysa en sonunda commit yaparak bu işlemlerin veritabanına yansıtılmasını isteriz. Örneğin:
@ -2749,12 +2749,12 @@ except Exception as e:
except sqlite3.Error as e:
conn.rollback()
Özel bir durum olarak execute işleminde eğer SQL SELECT komutu uygulanmışsa bu durumda transcation otomatik başlatılmamaktadır.
Özel bir durum olarak execute işleminde eğer SELECT komutu uygulanmışsa bu durumda transcation otomatik başlatılmamaktadır.
Transaction kavramı ve rollback işlemi birden fazla INSERT, UPDATE ve DELETE komutlarının peşi sıra geldiği durumlarda önemli olmaktadır.
Yoksa tek bir INSERT, UPDATE ya da DELETE komutu için rollback uygulamaya gerek yoktur. Yukarıda da beirttiğimiz gibi rollback işlemi
bir grup peşi sıra yapılan işlemin bir tanesi başarısız ise onların hiçbirini yapmamayı sağlamaktadır. commit işlemi ise onların
hepsini tek bir işlemmiş gibi atomik yapmayı sağlar.
Transaction kavramı ve rollback işlemi birden fazla INSERT, UPDATE ve DELETE komutlarının peşi sıra geldiği durumlarda önemli
olmaktadır. Yoksa tek bir INSERT, UPDATE ya da DELETE komutu için rollback uygulamaya gerek yoktur. Yukarıda da belirttiğimiz gibi
rollback işlemi bir grup peşi sıra yapılan işlemin bir tanesi başarısız ise onların hiçbirini yapmamayı sağlamaktadır. commit işlemi
ise onların hepsini tek bir işlemmiş gibi atomik yapmayı sağlar.
#------------------------------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------------------------------
@ -2772,7 +2772,7 @@ except Exception as e:
transaction'ı başlatan BEGIN (ya da BEGIN TRANSACTION) komutu eklenmelidr. Örneğin:
cur.executescript("""
BEGIN;
BEGIN TRANSACTION;
CREATE TABLE person(firstname, lastname, age);
CREATE TABLE book(title, author, published);
CREATE TABLE publisher(name, address);
@ -2794,9 +2794,8 @@ except Exception as e:
except sqlite3.Error as e:
conn.rollback()
Tabii yukarıda da belirttiğimiz gibi execute, executemany ve exceutescript metotları zaten otomatik trnsaction oluşturmaktadır.
Python programcıları da genellikle commit ve rollback gibi işlemleri SQL komutlarının içerisinde değil metot çağrılarıyla
yapmaktadır.
Tabii yukarıda da belirttiğimiz gibi execute, executemany metotları zaten otomatik trnsaction oluşturmaktadır. Python programcıları
da genellikle commit ve rollback gibi işlemleri SQL komutlarının içerisinde değil metot çağrılarıyla yapmaktadır.
#------------------------------------------------------------------------------------------------------------------------------------
import sqlite3
@ -2832,242 +2831,331 @@ except Exception as e:
etkisi olmayacaktır.
#------------------------------------------------------------------------------------------------------------------------------------
BURADA KALDIK
#------------------------------------------------------------------------------------------------------------------------------------
11. Ders 12/04/2025 - Cumartesi
#------------------------------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------------------------------
Aşağıda "school" veritabanı üzerinde temel işleler yapan konsol tabanlı basit bir program verilmiştir.
Aşağıda "school" veritabanı üzerinde temel işlemler yapan konsol tabanlı basit bir program örneği verilmiştir.
#------------------------------------------------------------------------------------------------------------------------------------
import sqlite3
def main():
try:
with sqlite3.connect(r'test.sqlite') as conn:
cur = conn.cursor()
create_tables(cur)
while True:
option = disp_menu()
if not option:
continue
match option:
case 1:
add_student(cur)
case 2:
add_school(cur)
case 3:
delete_student(cur)
case 4:
delete_school(cur)
case 5:
list_students(cur)
case 6:
list_school(cur)
case 7:
break
except sqlite3.Error as e:
print(e)
def create_tables(cur):
cur.executescript("""
CREATE TABLE IF NOT EXISTS school (school_id INTEGER PRIMARY KEY AUTOINCREMENT, school_name TEXT(64), school_type TEXT(64));
CREATE TABLE IF NOT EXISTS student(student_no INTEGER, student_name VARCHAR(64), school_id INTEGER, FOREIGN KEY("school_id") REFERENCES "school"("school_id"), PRIMARY KEY("student_no" AUTOINCREMENT));
""")
def disp_menu():
print('1) Öğrenci kaydı ekle')
print('2) Okul kaydı ekle')
print('3) Öğrenci sil')
print('4) Okul sil')
print('5) Öğrenci listele')
print('6) Okul listele')
print('7) Çıkış')
print()
try:
option = int(input('Seçiminiz:'))
if 1 <= option <= 7:
return option
raise ValueError()
script = """
BEGIN;
CREATE TABLE IF NOT EXISTS school(school_id INTEGER PRIMARY KEY AUTOINCREMENT, school_name VARCHAR(128), school_city VARCHAR(32));
CREATE TABLE IF NOT EXISTS student(student_id INTEGER PRIMARY KEY AUTOINCREMENT, student_no INTEGER,
student_name VARCHAR(64), school_id INTEGER);
"""
cur.executescript(script)
except Exception as e:
print(f'Geçersiz giriş: {e}')
return 0
def add_student(cur):
try:
name = input('Öğrencinin adı soyadı:')
no = int(input('Öğrencinin numarası:'))
school_id = int(input("Öğrencinin okul id'si:"))
cur.execute(f"SELECT school_id FROM school WHERE school_id = {school_id}")
if not cur.fetchall():
raise ValueError("Geçersiz okul id'si")
sqlcmd = f"INSERT INTO student(student_no, student_name, school_id) VALUES({no}, '{name}', {school_id})"
cur.execute(sqlcmd)
cur.connection.commit()
print('Kayıt başarılı biçimde eklendi...')
except sqlite3.Error as e:
print(f'Kayıt eklenemedi: {e}')
except ValueError as e:
print(f'Geçersiz Giriş: {e}')
except Exception as e:
print(f'Geçersiz giriş: {e}')
print()
print(e)
def disp_menu(items_list):
while True:
for menu_no, (menu_item, _) in enumerate(items_list, 1):
print(f'{menu_no}) {menu_item}')
print()
try:
option = int(input('Seçiminiz:'))
if option >= 1 and option <= 9:
break
except:
pass
print('\nGeçersiz seçenek!..\n')
return option
def add_school(cur):
try:
name = input('Okul adı:')
school_type = input('Okul türü:')
sqlcmd = f"INSERT INTO school(school_name, school_type) VALUES('{name}', '{school_type}')"
cur.execute(sqlcmd)
school_name = input('Okul ismi:').strip()
if school_name == '':
raise ValueError('Okulş ismi boş girilemez')
school_city = input('Okulun bulunduğu şehir:').strip()
if school_city == '':
raise ValueError('Şehir boş girilemez')
sql_cmd = f"INSERT INTO school(school_name, school_city) VALUES('{school_name}', '{school_city}')"
cur.execute(sql_cmd)
cur.connection.commit()
print('Kayıt başarılı biçimde eklendi...')
print('\nOkul başarılı bir biçimde eklendi...\n')
except sqlite3.Error as e:
print(f'Kayıt eklenemedi: {e}')
print(f'Eklemede sorun oluştu: {e}\n')
except Exception as e:
print(f'Geçersiz giriş: {e}')
print()
def delete_student(cur):
print(f'Hatalı giriş: {e}\n')
return True
def add_student(cur):
try:
no = int(input('Öğrenci Numarası'))
sqlcmd = f"DELETE FROM student WHERE student_no = {no}"
cur.execute(sqlcmd)
student_name = input('Öğrencinin adı:').strip()
if student_name == '':
raise ValueError('Öğrenci boş girildi')
student_no = int(input('Öğrencinin numarası:'))
school_id = int(input("Öğrencinin okul Id'si:"))
sql_cmd = f"INSERT INTO student(student_name, student_no, school_id) \
VALUES('{student_name}', {student_no}, {school_id})"
cur.execute(sql_cmd)
cur.connection.commit()
print('Kayıt başarılı biçimde silindi...')
print('\nÖğrenci başarılı bir biçimde eklendi...\n')
except sqlite3.Error as e:
print(f'Kayıt silinemedi: {e}')
print(f'Eklemede sorun oluştu: {e}\n')
except Exception as e:
print(f'Geçersiz giriş: {e}')
print()
def delete_school(cur):
print(f'Hatalı giriş: {e}\n')
return True
def list_student(cur):
try:
id = int(input("Dikkat! Bir okul silerken okula kayıtlı tüm öğrenciler de silinir\nOkul id'si:"))
sqlcmd = f"DELETE FROM school WHERE school_id = {id}"
cur.execute(sqlcmd)
sqlcmd = f"DELETE FROM student WHERE school_id = {id}"
cur.execute(sqlcmd)
cur.connection.commit()
print('Kayıt başarılı biçimde silindi...')
except sqlite3.Error as e:
cur.rollback()
print(f'Kayıt silinemedi: {e}')
except Exception as e:
print(f'Geçersiz giriş: {e}')
print()
def list_students(cur):
try:
condition = input('Koşul:').strip()
sqlcmd = "SELECT student_no, student_name, student.school_id, school_name FROM student, school WHERE student.school_id = school.school_id"
condition = input('Öğrenci için koşul:').strip()
sql_cmd = "SELECT student_id, student_name, student_no, school_name, school_city \
FROM student, school WHERE student.school_id = school.school_id"
if condition != '':
sqlcmd += f' AND {condition}'
cur.execute(sqlcmd)
print('\n-----------------------')
for student_no, student_name, school_id, school_name in cur.fetchall():
print(f'{student_no} {student_name} {school_id} ({school_name})')
print('-----------------------')
sql_cmd += f" AND {condition}"
cur.execute(sql_cmd)
print()
print(f"{'İd':5s}{'Adı Soyadı':20s}{'No':<5s}{'Okul İsmi':<30s}{'Şehir'}")
print('-' * 80)
for student_id, student_name, student_no, school_name, school_city in cur.fetchall():
print(f'{student_id:<5d}{student_name:20}{student_no:<5d}{school_name:<30s}{school_city}')
print('-' * 80)
print()
except sqlite3.Error as e:
print(e)
print(f'Aramada sorun oluştu: {e}\n')
except Exception as e:
print(f'Geçersiz giriş: {e}')
print()
print(f'Hatalı giriş: {e}\n')
return True
def erase_student(cur):
try:
student_id = int(input("Silinecek öğre3ncinin id'si:"))
sql_cmd = f"""SELECT student_id, student_name, student_no, school_name, school_city FROM student, school
WHERE student_id = {student_id} AND student.school_id = school.school_id"""
cur.execute(sql_cmd)
t = cur.fetchone()
if t is None:
print("\nBu id'ye ilişkin bir öğrenci yok!\n")
return
student_id, student_name, student_no, school_name, school_city = t
print(f'\n{student_id:<5d}{student_name:20}{student_no:<5d}{school_name:<30s}{school_city}\n')
confirm = input('Yukarıdaki öğrenciyi silmek istediğine emin misiniz (E)/(H):').lower()
if confirm == 'e':
sql_cmd = f"DELETE FROM student WHERE student_id = {student_id}"
cur.execute(sql_cmd)
cur.connection.commit()
print('\n1 kayır silindi...\n')
else:
print()
except sqlite3.Error as e:
print(f'Aramada sorun oluştu: {e}\n')
except Exception as e:
print(f'Hatalı giriş: {e}\n')
return True
def list_school(cur):
try:
condition = input('Koşul:').strip()
sqlcmd = "SELECT school_id, school_name, school_type FROM school"
condition = input('Okul için koşul:').strip()
sql_cmd = "SELECT school_id, school_name, school_city FROM school";
if condition != '':
sqlcmd += f' WHERE {condition}'
cur.execute(sqlcmd)
print('\n-----------------------')
for school_id, school_name, school_type in cur.fetchall():
print(f'{school_id}, {school_name}, {school_type}')
print('-----------------------')
sql_cmd += f" WHERE {condition}"
cur.execute(sql_cmd)
print()
print(f"{'id':<5s}{'Okul İsmi':<40s}{'Şehir'}")
print('-' * 80)
for school_id, school_name, school_city in cur.fetchall():
print(f'{school_id:<5d}{school_name:<40s}{school_city}')
print('-' * 80)
print()
except sqlite3.Error as e:
print(e)
print(f'\nListelemede sorun oluştu: {e}\n')
except Exception as e:
print(f'Geçersiz giriş: {e}')
print()
print(f'\nHatalı giriş: {e}\n')
return True
def erase_school(cur):
try:
school_id = int(input("Silinecek okulun id'si:"))
sql_cmd = f"SELECT school_id, school_name, school_city FROM school WHERE school_id = {school_id}"
cur.execute(sql_cmd)
t = cur.fetchone()
if t is None:
print("\nBu id'ye ilişkin bir okul yok!\n")
return
school_id, school_name, school_city = t
print(f'\n{school_id:<5d}{school_name:<40s}{school_city}\n')
confirm = input('Bir okulu sildiğiniz zaman o okuldaki tüm öğrencileri de silersiniz' + \
'Yukarıdaki okulu silmek istediğine emin misiniz (E)/(H):').lower()
if confirm == 'e':
try:
sql_cmd = f"""
BEGIN TRANSACTION;
DELETE FROM student WHERE school_id = {school_id};
DELETE FROM school WHERE school_id = {school_id};
COMMIT;
"""
cur.executescript(sql_cmd)
except sqlite3.Error as e:
cur.connection.rollback()
print(f'Silme işleminde hata oluştu: {e}\n')
print('\n1 kayıt silindi...\n')
else:
print()
except sqlite3.Error as e:
print(f'Aramada sorun oluştu: {e}\n')
except Exception as e:
print(f'Hatalı giriş: {e}\n')
return True
try:
main()
except:
pass
def exit_prog(cur):
return False
def main():
items_list = [
('Okul ekle', add_school),
('Öğrenci ekle', add_student),
('Öğrenci listele', list_student),
('Okul listele', list_school),
('Öğrenci sil', erase_student),
('Okul sil', erase_school),
('Çıkış', exit_prog),
]
try:
with sqlite3.connect('school.sqlite') as conn:
cur = conn.cursor()
create_tables(cur)
while True:
option = disp_menu(items_list)
_, f = items_list[option - 1]
if not f(cur):
break
except sqlite3.Error as e:
print(f'DB Error: {e}')
except Exception as e:
print(e)
main()
#------------------------------------------------------------------------------------------------------------------------------------
12. Ders 13/04/2025 - Pazar
#------------------------------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------------------------------
Pek çok VTYS kütüphanesi SQL komutlarında "yer tutucu" ya da başka bir deyişle "parametre" kullanımına izin vermektedir. Python'da
yer tutucular iki biçimde bulundurulmaktadır: "?" biçiminde ya da ":isim" biçiminde. "?" yer tutucusu isimsizdir. Ancak ":isim" yer tutucusu
isimlidir. Bu yer tutucular komut içerisinde değermiş gibi kullanılabilirler. Örneğin:
yer tutucular iki biçimde kullanılmaktadır: "?" biçiminde ya da ":isim" biçiminde. "?" yer tutucusu isimsizdir. Ancak ":isim" yer
tutucusu isimlidir. Bu yer tutucular komut içerisinde bir öğe gibi kullanılabilirler. Örneğin:
sqlcmd = "INSERT INTO student(student_no, student_name) VALUES(?, ?)"
Burada ilk "?" student_no için yerleştirilecek değeri, ikinci "?" ise student_name için yerleştirilecek değeri belirtmektedir. Aynı komut
şöyle de oluşturulabilirdir:
Burada ilk "?" student_no için yerleştirilecek değeri, ikinci "?" ise student_name için yerleştirilecek değeri belirtmektedir. Aynı
komut şöyle de oluşturulabilirdi:
sqlcmd = "INSERT INTO student(student_no, student_name) VALUES(:no, :name)"
Burada :no yer tutucusu student_no ile :name yer tutucusu ise student_name ile eşleştirilmektedir. Pekiyi bu yer tutuculara değerleri nasıl yerleştirilmektedir?
İşte aslında execute isimli metot işletilecek SQL cümlesinin yanı sıra ikinci parametresi ile yer tutucuların değerlerini dolaşılabilir bir nesne
biçiminde almaktadır. Örneğin:
Burada :no yer tutucusu student_no için, :name yer tutucusu ise student_name için yerleştirilecek değeri belirtmektedir. Pekiyi bu
yer tutuculara değerleri nasıl yerleştirilmektedir? İşte aslında Cursor sınıfının execute metodu işletilecek SQL cümlesinin yanı
sıra ikinci parametresi ile yer tutuculara yerleştirilecek değerleri de bizden istemektedir. Eğer yer tutucular "?" işareti ile
belirtilmişse bu durumda execute metodunun ikinci parametresi bir demet ya da liste olmalıdır. Demet ya da liste içerisindeki
elemanlar sırasıyla SQL komutundaki "?" yer tutucularının yerine yerleştirilmektedir. Örneğin:
sqlcmd = "INSERT INTO student(student_no, student_name) VALUES(?, ?)";
cur.execute(sqlcmd, (4523, "Rasim Özcan"))
sqlcmd = "INSERT INTO student(student_no, student_name, school_id) VALUES(?, ?, ?)";
cur.execute(sqlcmd, (523, 'Rasim Özcan', 3))
conn.commit()
Eğer yer tutucular isimliyse bu duurmda execute metodunun ikinci parametre bir sözlük nesnesi olamk zorundadır. Sözlüğün anahtarları
yer tutucuların simlerinden değerleri ise ter tutuculara yerleştirilecek değerlerden oluşur. Tabii artık yer tutucuların girilme sırasının bir önemi
kalmamaktadır. Örneğin:
Burada 525 değeri ilk "?" yerine, "Rasim Özcan" değeri ikinci "?" yerine ve 3 değeri ise üçüncü "?" yerine yerleştirilir. execute
metodu bu yerleştirmeyi yaptıktan sonra komutu VTYS'ye göndermektedir. Yerleştirme yapıldıktan sonra SQL komutu şu hale gelecektir:
sqlcmd = "INSERT INTO student(student_no, student_name) VALUES(:no, :name)";
cur.execute(sqlcmd, {'name': 'Sacit Özyıllmaz', 'no': 7372})
"INSERT INTO student(student_no, student_name, school_id) VALUES(523, 'Rasim Özcan', 3)"
Yazsısal değerlerin SQL komutunda tek tırnak içerisine alınmasını execute metodu zaten sağlamaktadır.
Eğer yer tutucular isimliyse bu durumda execute metodunun ikinci parametresi bir sözlük nesnesi olmak zorundadır. Sözlüğün anahtarları
yer tutucuların isimlerinden değerleri ise ter tutuculara yerleştirilecek değerlerden oluşur. Tabii artık yer tutucuların girilme
sırasının bir önemi kalmamaktadır. Örneğin:
sqlcmd = "INSERT INTO student(student_no, student_name, school_id) VALUES(:no, :name, :sid)";
cur.execute(sqlcmd, {'no': 523, 'name': 'Rasim Özcan', 'sid': 3})
conn.commit()
Yer tutucu kullanmanın ne avantajı vardır? İşte her defasında yeniden bir komut yazısı oluşturmak yerine yer tutucularla bir tane komut yazısı
oluşturup hep onu kullanmak çok daha pratik ve etkindir. Yani programcı işin başında programında gerekli SQL komutlarını yer tutucularla oluşturur
sonra da onların değerlerini execute metodunda verir. Örneklerden de gördüğünüz gibi yer tutucu eğer bir string ise onu tek tırnak içerisine programcı
almamaktadır. Yer tutucuyu yerleştiren execute metodu bunu yapmaktadır.
Buradaki isimlerde ':' karakterinin kullanılmadığına dikkat ediniz.
Pekiyi yer tutucu kullanmanın ne avantajı vardır? İşte her defasında yeniden bir komut yazısı oluşturmak yerine yer tutucularla
bir tane komut yazısı oluşturup hep onu kullanmak çok daha pratik ve etkindir. Yani programcı işin başında programında gerekli
SQL komutlarını yer tutucularla oluşturur sonra da onlar için değerleri execute metodunda belirtir. Bir kez daha anımsatmak istiyoruz:
Örneklerden de gördüğünüz gibi yer tutucu eğer bir string ise onu tek tırnak içerisine programcı almamaktadır. Yer tutucuyu yerleştiren
execute metodu bunu yapmaktadır.
Yer tutucuların işlevlerinin Python'a son versiyonlarla eklenen f'li string'lerle (string enterpolasyonuyla) sağlanabileceğini
düşünebilirsiniz. Ancak f'li string'ler programın akışı o noktaya geldiğinde bir kez oluşturulmaktadır. Örneğin:
student_no = 123
sql_cmd = f"SELECT * FROM student WHERE student_no = {student_no}"
print(sql_cmd) # SELECT * FROM student WHERE student_no = 123
student_no = 321
print(sql_cmd) # SELECT * FROM student WHERE student_no = 123
#------------------------------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------------------------------
execute ve executescript metotlarının dışında Cursor sınıfının bir de executemany isimli metodu vardır. Bu metodun kullanılabilmesi için
SQL komut yazısının yer tutucuyla oluşturulması gerekir. executemany metodunun ikinci parametresi bir demet listesi ya da bir sözlük listesi
olabilir. (Burada liste ya da demet yerine herhangi bir dolaşılabilir nesne de kullanılabilir.) Metot çağrıldığında dolaşılabilir nesnedeki
elemanlar tekl tek yer tutuculara yerleştirilip komut birden fazla kez uygulanmaktadır. Örneğin:
execute ve executescript metotlarının dışında Cursor sınıfının bir de executemany isimli metodu vardır. Bu metodun kullanılabilmesi
için SQL komut yazısının yer tutucuyla oluşturulması gerekir. executemany metodunun ikinci parametresi demetlerden ya da sözlüklerden
oluşan dolaşılabilir bir nesne olabilir. Metot çağrıldığında dolaşılabilir nesnedeki elemanlar tek tek yer tutuculara yerleştirilip
komut birden fazla kez uygulanmaktadır. Örneğin:
sqlcmd = "INSERT INTO student(student_no, student_name) VALUES(?, ?)";
cur.executemany(sqlcmd, [(8984, 'Kazım Tanış'), (6345, 'Fatma Aslan'), (8491, 'Hasan Kartal')])
sql_cmd = "INSERT INTO student(student_name, student_no, school_id) VALUES(?, ?, ?)"
cur.executemany(sql_cmd, [('Tayyar Altınkulaç', 456, 3), ('Salim Dündar', 632, 2)])
conn.commit()
Yer tutucvular isimliyse executemany metodunda bir sözlük listesi verilebilir. Örneğin:
Yukarıdaki executemany birden fazla execute ile aynı işleve sahiptir:
sqlcmd = "INSERT INTO student(student_no, student_name) VALUES(:no, :name)";
cur.executemany(sqlcmd, [{'no': 8984, 'name': 'Kazım Tanış'}, {'no': 6345, 'name': 'Fatma Aslan'}, {'no': 8491, 'name': 'Hasan Kartal'}])
sql_cmd = "INSERT INTO student(student_name, student_no, school_id) VALUES(?, ?, ?)"
cur.execute(sql_cmd, ('Tayyar Altınkulaç', 456, 3))
cur.execute(sql_cmd, ('Salim Dündar', 632, 2))
conn.commit()
executemany sayesinde bazı pratik işlemler yapılabilmektedir. Örneğin bir CSV dosyasından okuma yapan csv.reader fonksiyonu bize dolaşılabilir bir nesne
verir. Sonra her dolaşımda CSV dosyasındaki bir satır elde edilir. Biz doğrudan bu reader nesnesini executemany metodunun ikinci parametresine geçirebiliriz. Örneğin:
Yer tutucular isimliyse executemany metodunda bir sözlük listesi ya da sözlüklerden oluşan bir demet (aslında genel olarak sözlüklerden
oluşan dolaşılabilir bir nesne) verilebilir. Örneğin:
sql_cmd = "INSERT INTO student(student_name, student_no, school_id) VALUES(:name, :no, :sid)"
cur.executemany(sql_cmd, [{'name': 'Gökhan Abur', 'no': 387, 'sid': 5}, {'name': 'Timur Selçuk', 'no': 743, 'sid': 2}])
conn.commit()
executemany sayesinde bazı işlemler pratik biçimde yapılabilmektedir. Örneğin bir CSV dosyasından okuma yapan standart csv modülündeki
reader fonksiyonu bize dolaşılabilir bir nesne verir. Sonra her dolaşımda CSV dosyasındaki bir satır elde edilir. Biz doğrudan bu reader
fonksiyonunun verdiği nesneyi executemany metodunun ikinci parametresine geçirebiliriz. Örneğin:
import sqlite3
import csv
try:
with sqlite3.connect('school.sqlite') as conn:
with sqlite3.connect('school.sqlite') as conn, open('student.csv') as f:
cur = conn.cursor()
sqlcmd = "INSERT INTO student(student_no, student_name) VALUES(?, ?)";
with open('student.csv') as f:
cur.executemany(sqlcmd, csv.reader(f))
conn.commit()
sql_cmd = "INSERT INTO student(student_name, student_no, school_id) VALUES(?, ?, ?)"
cur.executemany(sql_cmd, csv.reader(f))
conn.commit()
except sqlite3.Error as e:
print(e)
except Exception as e:
print(e)
#------------------------------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------------------------------
Tabii yer tutucular yalnızca INSERT INTO komutunda değil diğer komutlarda da kullanılabilmektedir. Örneğin:
@ -3081,75 +3169,114 @@ except:
cur.executemany(sqlcmd, [(9981, ), (8984, )])
conn.commit()
except sqlite3.Error as e:
print(e)
#------------------------------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------------------------------
11. Ders 16/01/2023 - Pazartesi
print(e)
#------------------------------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------------------------------
Daha önceden de belirttiğimiz gibi VTYS'lerin pek çok built-in fonksiyonları vardır. Bu fonksiyonları sorgulamalarda kullanabiliriz.
Aşağıdai örnekte "student" tablosundaki öğrencilerin isimlerinin uzunlukları elde edilmiştir.
Aşağıda built-in length fonksiyonunun kullanımına ilişkin bir örnek görüyorsunuz:
sql_cmd = "SELECT * FROM student WHERE length(student_name) = ?"
cur.execute(sql_cmd, (10, ))
students = cur.fetchall()
for student in students:
print(student)
Burada adı soyadı 10 karakter olan öğrencilerin listesi elde edilmektedir.
#------------------------------------------------------------------------------------------------------------------------------------
import sqlite3
try:
with sqlite3.connect('school.sqlite') as conn:
cur = conn.cursor()
sqlcmd = "SELECT length(student_name) FROM student"
for n, in cur.execute(sqlcmd):
print(n)
cur = conn.cursor()
sql_cmd = "SELECT * FROM student WHERE length(student_name) = ?"
cur.execute(sql_cmd, (10, ))
students = cur.fetchall()
for student in students:
print(student)
except sqlite3.Error as e:
print(e)
except Exception as e:
print(e)
#------------------------------------------------------------------------------------------------------------------------------------
Aşağıdaki örnekte de ad ve soyadları 10 karakter olan öğrenciler elde edilmiştir.
Tabii biz SELECT cümlesinde veirtabanındaki sütun isimlerini bu fonksiyonlara sokarak sütun isimleri yerine bunların çıktılarını
da elde edebiliriz. Örneğin "school.sqlite" veritabaınındaki öğrencilerin ad ve soyadlarının uzublukları aşağıdaki gibi elde
edilebilir:
sql_cmd = "SELECT length(student_name) FROM student"
cur.execute(sql_cmd)
students = cur.fetchall()
for student in students:
print(student)
#------------------------------------------------------------------------------------------------------------------------------------
import sqlite3
try:
with sqlite3.connect('school.sqlite') as conn:
cur = conn.cursor()
sqlcmd = "SELECT student_name FROM student WHERE length(student_name)=10"
for n, in cur.execute(sqlcmd):
print(n)
cur = conn.cursor()
sql_cmd = "SELECT length(student_name) FROM student"
cur.execute(sql_cmd)
students = cur.fetchall()
for student in students:
print(student)
except sqlite3.Error as e:
print(e)
except Exception as e:
print(e)
#------------------------------------------------------------------------------------------------------------------------------------
Kendimizn yazdığı bir Python fonksiyonunu SQL komutunda da kullanabiliriz. Bunun için kullanılacak olan fonksiyonun Connection nesnesinin create_function
isimli metoduyla yaratılması gerekir. create_function metodunun parametrik yapısı şöyledir:
Bazı built-in fonksiyonlar pek çok VTYS'de aynı biçimde bulunmaktadır. Ancak pek çok fonksiyon da VTYS'ye özgüdür. Bu nedenle hangi
VTYS'de çalışıyorsanız o VTYS'ye özgü fonksiyonları o VTYS'nin kendi dokümanlarından elde edebilirsiniz.
Kendimizin yazdığı bir Python fonksiyonunu SQL komutunda da kullanabiliriz. Bunun için kullanılacak olan fonksiyonun Connection
nesnesinin create_function isimli metoduyla yaratılması gerekir. create_function metodunun parametrik yapısı şöyledir:
create_function(name, narg, func, *, deterministic=False)
Metodun birinci parametresi fonksiyonun SQL içerisinden kullanılacak ismini belirtmektedir. Bu ismin fonksiyonun gerçek ismiyle aynı olması
gerekmez. İkinci parametre fonksiyonun parametre sayısını belirtmektedir. Üçüncü parametre de fonksiyon Python'daki ismini belirtir.
Metodun birinci parametresi fonksiyonun SQL içerisinden kullanılacak ismini belirtmektedir. Bu ismin fonksiyonun gerçek ismiyle
aynı olması gerekmez. İkinci parametre fonksiyonun parametre sayısını, üçüncü parametre ise Python fonksiyon nesnesini belirtmektedir.
Biz bu üçüncü parametreye çağrılmasını istediğimiz fonksiyonun ismini girebiliriz. create_function fonksiyonunu çağırdıktan sonra
artık biz belirlediğimiz bu fonksiyon ismini SQL komutunda kullanabiliriz. Fonksiyon SQL komutunda kullanıldığında komutta belirtilen
sütun bilgileri belirlenen fonksiyona parametre olarak aktarılacaktır. Örneğin biz komutta bu fonksiyona student_name ve student_no
sütunlarını argüman olarak verirsek student_name sütunu fonksiyona str olarak, student_no sütunu ise int olarak aktarılacacaktır.
Bu biçimde belirlediğimiz fonksiyon SQL komutu uygulandığında fonksiyonun geri döndürdüğü değer komutta kullanılmaktadır. SQL büyük
harf küçük harf duyarlılığı olan (case sensitive) bir dil değildir. Yani örneğin biz create_function metoduna fonksiyon ismini küçük
harfle versek bile onu komut içerisimde büyük harfle kullanabiliriz.
Örneğin:
Fonksiyona SQL komutunda geçirilen sütun parametreleri fonksiyonun içerisinden doğrudan kullanılabilmektedir. Parametrenin türü sütunun
türüyle ilgili olmaktadır. Örneğin student_name sütunu fonksiyona str parametresi olarak geçirilmektedir.
sql_cmd = "SELECT myfunc(student_name), student_no FROM student"
Aşağıdaki örnekte myfunc isimli fonksiyon SQL içerisinde reverse ismiyle kullanılmıştır.
Bu SQL cümlesi çalıştırıldığında student_name sütunundaki her isim önce myfunc fonksiyonuna parametre olarak geçirilecek, sonra
bu fonksiyonun geri dönüş değeri elde edilip SELECT tarafından işlenecektir.
Aşağıdaki örnekte foo isimli fonksiyon SQL içerisinde "myfunc" ismiyle kullanılmaktadır. Bu örnekte öürencinin ismi ve numarası
birleştirilerek tek bir sütunmuş gibi elde edilmektedir.
#------------------------------------------------------------------------------------------------------------------------------------
import sqlite3
def myfunc(name, no):
return name[.-1] + ' ' + str(no)[.-1]
def foo(name, no):
return name + ', ' + str(no)
try:
with sqlite3.connect('school.sqlite') as conn:
conn.create_function('reverse', 2, myfunc)
cur = conn.cursor()
sqlcmd = "SELECT reverse(student_name, student_no) FROM student"
for n, in cur.execute(sqlcmd):
print(n)
sql_cmd = "SELECT myfunc(student_name, student_no) FROM student"
conn.create_function('myfunc', 2, foo)
cur.execute(sql_cmd)
students = cur.fetchall()
for name, in students:
print(name)
except sqlite3.Error as e:
print(e)
except Exception as e:
print(e)
<BURADA KALDIK>
#------------------------------------------------------------------------------------------------------------------------------------
Aşağıdaki örnekte zaten var olan length built-in fonksiyonunun mylength ismiyle başka bir versiyonu yazılmıştır.
#------------------------------------------------------------------------------------------------------------------------------------
@ -3171,9 +3298,9 @@ except sqlite3.Error as e:
print(e)
#------------------------------------------------------------------------------------------------------------------------------------
Tabii VTYS'de zaten var olan built-in fonksiyonları gereksiz bir biçimde yeniden yazmayınız. Çalıştığınız VTYS'deki
built-in fonksiyonların listesini dokümanlardan elde edip incelemelisiniz. Örneğin substr isimli SqLite fonksiyonu
belli bir indeksten itibaren (ilk indeks 1'dir) n tane karakteri elde etmektedir.
Tabii VTYS'de zaten var olan built-in fonksiyonları gereksiz bir biçimde yeniden yazmayınız. Çalıştığınız VTYS'deki built-in
fonksiyonların listesini dokümanlardan elde edip incelemelisiniz. Örneğin substr isimli SqLite fonksiyonu belli bir indeksten itibaren
(ilk indeks 1'dir) n tane karakteri elde etmektedir.
#------------------------------------------------------------------------------------------------------------------------------------
import sqlite3
@ -3214,7 +3341,8 @@ except Exception as e:
print(e)
#------------------------------------------------------------------------------------------------------------------------------------
text_factory örnek özniteliği default durumda str fonksiyonunu almaktadır. Yani SELECT edilen yazısal sütunlar str fonksiyonuna sokulmaktadır.
text_factory örnek özniteliği default durumda str fonksiyonunu almaktadır. Yani SELECT edilen yazısal sütunlar str fonksiyonuna
sokulmaktadır.
#------------------------------------------------------------------------------------------------------------------------------------
import sqlite3