Sqlite otomatik artan numara

Mrb arkadaşlar, veritabanımda Id si ortak otomatik artan 2 table var . Ogrenci_tahsilat(ogrenci_no, adi, soyadi,tahsil_tutarı, tahsil_tarih, gelir_id)
Gelir(gelir_id, gelir_turu, gelir_adı, gelir_miktarı, aciklama).

öğrenci tahsilatı yapıldığında gelir_id otomatik numara alacak aynı numarayla gelir tablosuna da aynı anda otomatik olarak kaydedilecek.
otomatik numara tespit edilip gider tablosuna nasıl kaydedilir? Tşkler…

Merhaba, rica etsem kodları paylaşabilir misiniz?

import sqlite3
from datetime import *
vt=sqlite3.connect('ornek.db')
islem=vt.cursor()
#a=datetime.now().strftime('%d/%m/%Y %H:%M:%S')
islem.execute("CREATE TABLE IF NOT EXISTS O_Tahsilat(ogrenci_no INTEGER,tahsilat,tah_tarih,gelir_id INTEGER PRIMARY KEY AUTOINCREMENT)")
vt.commit()
islem.execute("CREATE TABLE IF NOT EXISTS Gelir(gelir_id INTEGER PRIMARY KEY AUTOINCREMENT,gelir_turu,gelir_adi,miktar,gelir_tarihi)")
vt.commit()
tahsil=((74,290,"28/02/2019"),(85,400,"31/03/2019"),(611,711,"30/04/2014"),(85,900,"02/08/2019"),(89,666,"02/06/2019"))
#aşağıda rastgele kayıt ekledim.........................................................................
islem.executemany("INSERT INTO O_Tahsilat(ogrenci_no,tahsilat,tah_tarih)VALUES(?,?,?)",tahsil)
#aşağıda ise o_tahsilat tablosuna kayıt eklediğimde oluşacak olan gelir_id numarası değerinde gelir tablosunda otomatik olartak kayıt eklemesini istiyorumm
islem.execute("INSERT INTO O_Tahsilat(ogrenci_no,tahsilat,tah_tarih)VALUES(111,522,'12/12/2012')")
vt.commit()
sonkayit=islem.lastrowid
print(sonkayit)
islem.execute("SELECT * FROM O_tahsilat WHERE(gelir_id=:gelir_id)",{"gelir_id":sonkayit})
veriler=islem.fetchone()
print(veriler)
gelir_kayit=[]
gelir_kayit.append(veriler[3])
gelir_kayit.append('Ö.Tahsilat')
gelir_kayit.append(veriler[0])
gelir_kayit.append(veriler[1])
gelir_kayit.append(veriler[2])
islem.execute("INSERT INTO Gelir(gelir_id,gelir_turu,gelir_adi,miktar,gelir_tarihi)VALUES(?,?,?,?,?)",gelir_kayit)
vt.commit()

bişeyler yaptım ama bu yöntem garanti yöntem midir emin değilim

O_Tahsilat tablosunun son satırındaki gelir id, öğrenci no, miktar, tarih bilgileri Gelir tablosuna ekleniyor. Ayrıca, scripti üst üste çalıştırınca, gelir id'ler otomatik olarak artıyor.

Yani yöntemde sıkıntı var mı?

Bir sıkıntı görmedim ben. Sizin istediğiniz şeyi yapmıyor mu yoksa?

Yapıyor fakat; 10bin satırlı kayıt olduğunu düşünürsek sistemi yormaz mı ?
Lastrowid çalışma mantığı nedir? Son kayda ulaşmak için indexleme mi yapıyor?

Sistemi yorup yormayacağını bilemem, bazen yazdığımız bir kod yüzünden de kaynaklanabilir bu, alternatif bir kodla bazı işlemlerin gerçekleşme zamanı kısaltılabilir.

Lastrowid, adı üzerinde en son düzenlenmiş olan satırın id’sini okuyan bir özellik.

Tşk ederim .
Garanti derken şunu demek istiyorum. Veritabanını 1 den fazla kişinin kullandığını düşünürsek
mesela 60 nolu kayıt yaptım. son kayıt numarası 60. Bu numarayı alıp gelir tablosuna eklemeden hemen önce başka biri kayıt yaparsa sistem 60 değil de 61 numaralı kaydı alır (çok zor bir ihtimalde olsa )
bu durum yanlışlıklara yol açar. Yanlış mı düşünüyorum bilmiyorum?

Siz zaten 60 numaralı kaydı yapınca otomatik olarak o kayıt gelir tablosuna eklenmiyor mu? Yani şöyle bir durumdan bahsediyorsunuz herhalde, sizinle aynı anda kayıt yapmaya çalışan bir başka kullanıcı sizden önce o kaydı gerçekleştirirse, sizin kaydınız 61. kayıt olur. Veya siz kaydı önce gerçekleştirirseniz bu sefer onun eklediği 61. kayıt olur.

Günaydın arkadaşlar
Yukarıdaki kodları örnek olsun diye yazdım projeme henüz eklemedim bir senaryodan bahsediyorum.
senaryo:
tahsilat kaydı yapıldı son id 60 oldu. lastrowid (veritabanında 1000 kayıt olduğunu düşünelim) komutu çalıştırılırdığında atıyorum 1/500 sn de gerçekleşti. Bir başkası 1/300 sn önce tahsilat kaydı yaptı son numara 61 oldu ve son 2 kişi 61 numaralı kayda erişmiş oldu.
lastrow id çalışma mantığını o yüzden merak ettim.

Bilmem? Dene ve gor. (Olcusuz optimizasyon ile ilgili butun sorulara bu cevabi veriyorum bu arada, kisisel algilamayiniz.)

Evet, buna literaturde race condition deniliyor.

lastrowid gibi hack’ler kimi zaman baglantiya veya cursor’a baglaniyor; bu durumda 60. ile 61. kayit ayni baglanti veya cursor uzerinde yapilmazsa lastrowid’leri karismiyor. Bakalim…

Evet, Cursor.lastrowid olduguna gore race condition yoktur.

Bu arada “hack” dememin sebebi dogrusunun INSERT ... RETURNING id gibi data donduren bir INSERT kullanmak olmasi (ama bu da standart degil). SQLite burada bir suru developer’in yaptigi seyi yapip MySQL’in sacmaligini ornek almis.

Cok guzel! Race condition’lari gorebilmek ve hatta duplike edecek senaryolari cikarmak, cok iyi programcilari iyi programcilardan ayiran bir ozellik.

lastrowid’yi SELECT MAX(id) FROM table olarak dusunursek aynen oyle ama dedigim gibi cursor’a/transaction’a bagli gibi duruyor.

Bu arada soyle anlatmak daha kolay olabilir:

  1. ← INSERT #1
  2. 60 insert edildi
  3. ← SELECT MAX(id) #1
  4. ← INSERT #2
  5. 61 insert edildi
  6. ← SELECT MAX(id) #2
  7. ilk select calisti: → 61
  8. ikinci select calisti: → 61

(Ben de rahat bir notasyon bulmak icin yazdim siralamayi)

Aib aydınlatıcı bilgilerin için tşk ederim. Herkese iyi bayramlar dilerim…