IndexError: tuple index out of range

Kullanıcı arayüzde tabloya veri tabanını çekeceğim dosyayı yüklüyor. Daha sonra tablo üzerinden değişim yapıp değiştir tarzında bir butona bastığında yüklediği veri tabanına tablonun yeni halini eklemeye çalışıyorum. Fakat bu satırda:
imlec.execute("INSERT INTO {} VALUES({})".format(tablo_adi[0][0]),veriler)
bu hatayı alıyorum:
IndexError: tuple index out of range

print(type(veriler)) dediğimde çıktısı: <class 'list'>
print(type(tablo_adi[0][0])) dediğimdeyse çıktı: <class 'str'> oluyor.

Bu hatayı nasıl düzeltebilirim?

Merhaba,

Kodlarınızı sadeleştirerek bizimle paylaşabilir misiniz? Test etmeden bir şey söylemek zor.

from arayuz import Ui_MainWindow as arayuz
from PyQt5.QtWidgets import QMainWindow,QApplication,QFileDialog
from PyQt5 import QtWidgets
import os
import sqlite3

class goster_veritabani(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ac_pencere()
        
    def dosya_sec(self):
        self.file_dialog = QFileDialog(self)
        self.open_file = self.file_dialog.getOpenFileName(self,"Dosya Aç",os.getenv("HOME"))
        return self.open_file[0]
    
    def veri_yukle(self):
        global tablo_adi
        global imlec
        global baglanti
        dosya = self.dosya_sec()
        with sqlite3.connect(dosya) as baglanti:
            imlec = baglanti.cursor()
            imlec.execute("SELECT name FROM sqlite_master")
            tablo_adi = imlec.fetchall()
            imlec.execute("SELECT * FROM {ta}" .\
                          format(ta=tablo_adi[0][0]))
            veri = imlec.fetchall()
            for satir_say, satir_veri in enumerate(veri):
                for sutun_say, veri in enumerate(satir_veri):
                    self.ui.tablo.setItem(satir_say,sutun_say,QtWidgets.QTableWidgetItem(str(veri)))
        
    def veri_isle(self,veriler):
        print(veriler)
        imlec.execute("INSERT INTO {} VALUES({})".format(tablo_adi[0][0]),veriler)
        baglanti.commit()
        
    def veri_cek(self):
        satir_sayisi = self.ui.tablo.rowCount()
        sutun_sayisi = self.ui.tablo.columnCount()
        for satir in range (satir_sayisi):
            veri_satir = []
            for sutun in range (sutun_sayisi):
                parcacik = self.ui.tablo.item(satir,sutun)
                if(parcacik and parcacik.text):
                    veri_satir.append(parcacik.text())
                else:
                    veri_satir.append('NULL')
            self.veri_isle(veri_satir)
        
    def baglantilar(self):
        self.ui.buton_yukle.clicked.connect(self.veri_yukle)
        self.ui.buton_degistir.clicked.connect(self.veri_cek)
        
    def ac_pencere(self):
        self.ui = arayuz()
        self.ui.setupUi(self)
        self.baglantilar()

if __name__ == "__main__":
    uygulama = QApplication([])
    ana_pencere = goster_veritabani()
    ana_pencere.show()
    uygulama.exec_()

Arayüz kodları:

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(852, 765)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setStyleSheet("#centralwidget{background-color: rgb(0, 0, 0);\n"
"background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255));\n"
"}")
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.tablo = QtWidgets.QTableWidget(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setStrikeOut(False)
        font.setKerning(True)
        self.tablo.setFont(font)
        self.tablo.viewport().setProperty("cursor", QtGui.QCursor(QtCore.Qt.IBeamCursor))
        self.tablo.setMouseTracking(False)
        self.tablo.setTabletTracking(False)
        self.tablo.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.tablo.setStyleSheet("background-color: rgb(255, 228, 160);\n"
"color: rgb(0, 0, 0);\n"
"selection-color: rgb(255, 253, 237);\n"
"selection-background-color: rgb(198, 172, 110);")
        self.tablo.setInputMethodHints(QtCore.Qt.ImhNone)
        self.tablo.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.tablo.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.tablo.setLineWidth(1)
        self.tablo.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.tablo.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
        self.tablo.setDragEnabled(False)
        self.tablo.setDefaultDropAction(QtCore.Qt.IgnoreAction)
        self.tablo.setAlternatingRowColors(False)
        self.tablo.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
        self.tablo.setShowGrid(True)
        self.tablo.setGridStyle(QtCore.Qt.DotLine)
        self.tablo.setWordWrap(True)
        self.tablo.setCornerButtonEnabled(False)
        self.tablo.setRowCount(100)
        self.tablo.setColumnCount(30)
        self.tablo.setObjectName("tablo")
        self.tablo.horizontalHeader().setVisible(False)
        self.tablo.verticalHeader().setVisible(True)
        self.tablo.verticalHeader().setCascadingSectionResizes(False)
        self.tablo.verticalHeader().setHighlightSections(True)
        self.tablo.verticalHeader().setSortIndicatorShown(False)
        self.tablo.verticalHeader().setStretchLastSection(False)
        self.verticalLayout.addWidget(self.tablo)
        self.gridLayout = QtWidgets.QGridLayout()
        self.gridLayout.setObjectName("gridLayout")
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem, 3, 0, 1, 1)
        self.buton_cik = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(25)
        self.buton_cik.setFont(font)
        self.buton_cik.setStyleSheet("background-color: rgb(0, 0, 0);\n"
"color: rgb(201, 195, 183);")
        self.buton_cik.setObjectName("buton_cik")
        self.gridLayout.addWidget(self.buton_cik, 4, 1, 1, 1)
        self.buton_yukle = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(26)
        self.buton_yukle.setFont(font)
        self.buton_yukle.setStyleSheet("background-color: rgb(0, 0, 0);\n"
"color: rgb(255, 170, 127);\n"
"")
        self.buton_yukle.setObjectName("buton_yukle")
        self.gridLayout.addWidget(self.buton_yukle, 2, 1, 1, 1)
        self.buton_degistir = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(26)
        self.buton_degistir.setFont(font)
        self.buton_degistir.setStyleSheet("background-color: rgb(0, 0, 0);\n"
"color: rgb(255, 170, 127);\n"
"")
        self.buton_degistir.setObjectName("buton_degistir")
        self.gridLayout.addWidget(self.buton_degistir, 3, 1, 1, 1)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem1, 3, 2, 1, 1)
        self.verticalLayout.addLayout(self.gridLayout)
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.tablo.setSortingEnabled(False)
        self.buton_cik.setText(_translate("MainWindow", "ÇIKIŞ"))
        self.buton_yukle.setText(_translate("MainWindow", "DOSYA YÜKLE"))
        self.buton_degistir.setText(_translate("MainWindow", "DEĞİŞTİR"))


Siz veritabanındaki satır verileri üzerinde değişiklik yapmıyorsunuz, değiştirdiğiniz satırları yeni satır olarak ekliyorsunuz.

veri_isle fonksiyonunu şu şekilde değiştirdim, ekleme gerçekleşecek ama yine hata alacaksınız.

        veriler = [i for i in veriler if i != "NULL"]
        imlec.execute(f"INSERT INTO {tablo_adi[0][0]} VALUES({', '.join('?' * len(veriler))})", veriler)

bir tane UPDATE ifadesi yazmanız gerekiyor.

VALUES()'un içinde "?, ?, ?" gibi kaç adet sütun varsa o kadar soru işareti olması gerekiyor, ekleyeceğiniz veriler de SQL ifadesinden sonra gelmeli. Yani imlec.execute'a iki parametre yazmalısınız, birisi SQL ifadesi, diğeri de veriler.

Ama önce sizin bir UPDATE ifadesi yazmanız gerekiyor. Ve programınız da üzerinde değişiklik yapılan satırları tespit edip, o satırlardaki sütunları güncellemeli.

1 Beğeni

Dediğinizi şu şekilde denedim:

    def veri_isle(self,veriler):
        secili_satir = self.ui.tablo.selectedItems()
        for i in range (sayac_satir):
            satir_kntrl = self.ui.tablo.item(i,0)
            if secili_satir[0] == satir_kntrl :
                sorgu = (f"UPDATE {tablo_adi[0][0]} SET ({', '.join('?' * len(veriler))}) WHERE secili_satir[0] = ?")
                imlec.execute(sorgu,(veriler,satir_kntrl.text()))
                baglanti.commit()
    def veri_cek(self):#Bu fonksiyonda iki değişiklik yaptım.
        global sayac_satir#Birincisi bu satırı ekledim.
        satir_sayisi = self.ui.tablo.rowCount()
        sutun_sayisi = self.ui.tablo.columnCount()
        sayac_satir = 0
        for satir in range (satir_sayisi):
            sayac_satir = sayac_satir+1
            veri_satir = []
            for sutun in range (sutun_sayisi):
                parcacik = self.ui.tablo.item(satir,sutun)
                if(parcacik and parcacik.text):
                    veri_satir.append(parcacik.text())
                else:
                    break#İkincisi bu satırı değiştirdim.
            self.veri_isle(veri_satir)

Ama bu satırda hata alıyorum :imlec.execute(sorgu,(veriler,satir_kntrl.text()))
Hata: OperationalError: near "?": syntax error
Yine sorgunun yazımında yanlış yapıyorum, burayı nasıl düzeltebilirim?

Kodlarınızı düzenledim. Gerekli yerlere açıklamalar ekledim. Kodlar çalışıyor, veritabanında değişiklik yapılabiliyor artık. Bir bakın isterseniz.

#!/usr/bin/python3.8
# -*- coding: utf-8 -*-

from arayuz import Ui_MainWindow as arayuz
from PyQt5.QtWidgets import QMainWindow,QApplication,QFileDialog
from PyQt5 import QtWidgets
import os
import sqlite3

class goster_veritabani(QMainWindow):
    def __init__(self):
        super().__init__()
        self.tablo = []
        self.columns = []
        self.tablo_adi = None
        self.imlec = None
        self.baglanti = None
        self.ac_pencere()
        
    def dosya_sec(self):
        self.file_dialog = QFileDialog(self)
        self.open_file = self.file_dialog.getOpenFileName(
            self,
            "Dosya Aç",
            os.getenv("HOME")
        )
        return self.open_file[0]
    
    def veri_yukle(self):
        dosya = self.dosya_sec()
        self.baglanti = sqlite3.connect(dosya)
        self.imlec = self.baglanti.cursor()
        self.imlec.execute("SELECT name FROM sqlite_master")
        self.tablo_adi = self.imlec.fetchall()
        self.imlec.execute(
            "SELECT * FROM {ta}".format(ta=self.tablo_adi[0][0])
        )
        veri = self.imlec.fetchall()
        # Orijinal veriler tabloda tutulacak, veriler üzerinde değişiklik
        # yapılırsa bu tablo karşılaştırma için kullanılacak.
        # Siz verileri parcacik.text() diye çektiğiniz için ben bütün verileri
        # string verisine dönüştürdüm.
        self.tablo = [[str(j) for j in i] for i in veri]
        # Sütun ismi için.
        self.columns = [i[0] for i in self.imlec.description]
        for satir_say, satir_veri in enumerate(veri):
            for sutun_say, veri in enumerate(satir_veri):
                self.ui.tablo.setItem(
                    satir_say,
                    sutun_say,
                    QtWidgets.QTableWidgetItem(str(veri))
                )
        
    def veri_isle(self, veriler):
        for orijinal, editted in zip(self.tablo, veriler):  # tablo ile GUI'deki veriler karşılaştırılacak.      
            if orijinal != editted:  # Eğer tablonun satır verisi, gui'deki satır verisine eşit değilse
                for index, (i, j) in enumerate(zip(orijinal, editted)):  # Satır verisindeki her bir sütun için
                    if i != j:  # Sütun değerlerinin aynı olup olmadığına bakılacak. Eğer aynı değilse,
                        # Aşağıdaki ifade ile tablo verisi değiştirilecek.
                        sorgu = f"UPDATE {self.tablo_adi[0][0]} SET " \
                            f"{self.columns[index]} = ? " \
                            f"WHERE {self.columns[1]} = ?"
                        self.imlec.execute(sorgu, (j, orijinal[1]))
        # Değişiklikleri işleme sokuyoruz.
        self.baglanti.commit()
        # Veritabanını kapatıyoruz.
        self.baglanti.close()
                
    def veri_cek(self):
        veriler = []
        for satir in range(len(self.tablo)):  # Tablodaki satır sayısı kadar
            veri_satir = []  # Satır oluştur
            for sutun in range(len(self.tablo[0])):  # Bir satırdaki sütun sayısı kadar
                parcacik = self.ui.tablo.item(satir, sutun)  # verileri al
                veri_satir.append(parcacik.text()) # Alınan verileri satır verisine ekle
            veriler.append(veri_satir)  # Satır verisini de verilere ekle.
        self.veri_isle(veriler)  # veri_isle fonksiyonuna verileri argüman olarak ver.
        
    def baglantilar(self):
        self.ui.buton_yukle.clicked.connect(self.veri_yukle)
        self.ui.buton_degistir.clicked.connect(self.veri_cek)
        
    def ac_pencere(self):
        self.ui = arayuz()
        self.ui.setupUi(self)
        self.baglantilar()

if __name__ == "__main__":
    uygulama = QApplication([])
    ana_pencere = goster_veritabani()
    ana_pencere.show()
    uygulama.exec_()

Sizin SQL ifadenizde bir hata vardı, ifadenin olması gereken hali şöyle:

f"UPDATE {tablo_ismi} SET {sutun_ismi} = ? WHERE {sutun_ismi} = ?"

WHERE'den sonraki sütun ismi, illa ki SET ile değiştirilecek sütun olmak zorunda değil, ama olabilir de.

1 Beğeni