pythonsqlite

I cannot delete an item in a table with Python and SQLite3


Bookstore management.

I am creating a program that manage bookstores. I want to add a delete option in it. I can create multiples bookstores in my program and add multiple books in a bookstore. I want the delete option for being able to correct eventual human mistakes using a program. Let me show you my codes

#filename: liv.py (liv is book in Haitian Creole)

class Liv: # That class create a book
    def __init__(self, tit, otè, id = None):
        #self.id = id
        self.tit = tit
        self.otè = otè
        self.disponib = True # Liv lan disponib pa defo
        self.id = id
                

#filename: database.py

import sqlite3
from liv import Liv

# bibliyotek means bookstore in Haitian
class Database:
    def __init__(self, db_name="bibliyotek.db"):
        self.conn = sqlite3.connect(db_name)
        self.cursor = self.conn.cursor()
        self.create_tables()

    def create_tables(self):
        # Kreye tab pou bibliyotèk ak liv yo
        self.cursor.execute("""
        CREATE TABLE IF NOT EXISTS bibliyotek (
            id INTEGER PRIMARY KEY,
            nom TEXT NOT NULL
        )
        """)

        
        self.cursor.execute("""
        CREATE TABLE IF NOT EXISTS liv (
            id INTEGER PRIMARY KEY,
            tit TEXT,
            otè TEXT,
            bibliyotek_id INTEGER,
            FOREIGN KEY (bibliyotek_id) REFERENCES bibliyotek(id)
        )
        """)
        self.conn.commit()

    def ajoute_bibliyotek(self, nom):
        bibliyotek_id = self.get_bibliyotek_id(nom)
        if bibliyotek_id is None:
            self.cursor.execute("INSERT INTO bibliyotek (nom) VALUES (?)", (nom,))
            self.conn.commit()
            return self.cursor.lastrowid
        return bibliyotek_id
    
    def get_bibliyotek_id(self, nom):
        self.cursor.execute("SELECT id FROM bibliyotek WHERE nom = ?", (nom,))
        result = self.cursor.fetchone()
        return result[0] if result else None

    def ajoute_liv(self, liv, bibliyotek_id):
        self.cursor.execute(
            "INSERT INTO liv (tit, otè, bibliyotek_id) VALUES (?, ?, ?)",
            (liv.tit, liv.otè, bibliyotek_id)
        )
        self.conn.commit()
        liv_id = self.cursor.lastrowid # Rekipere id a otomatikman
        return liv_id # Retounen id nouvo liv la

    def get_bibliyotek_yo(self):
        self.cursor.execute("SELECT id, nom FROM bibliyotek")
        rows = self.cursor.fetchall()
        return rows
    

    def get_liv_pa_bibliyotek(self, bibliyotek_id):
        self.cursor.execute("SELECT id, tit, otè FROM liv WHERE bibliyotek_id = ?", (bibliyotek_id,))
        rows = self.cursor.fetchall()
        return [Liv(tit, otè, id=liv_id) for tit, otè, liv_id in rows]
        # return Liv(id=liv_id, tit, otè)

    def close(self):
        self.conn.close()

    def efase_bibliyotek(self, bibliyotek_id): # Delete bookstore function, it works well
        self.cursor.execute("SELECT COUNT(*) FROM liv WHERE bibliyotek_id  = ?", (bibliyotek_id,))
        liv_count = self.cursor.fetchone()[0]

        if liv_count > 0:
            return False # gen liv nan bibliytèk la li poko ka efase
        else:
            # self.cursor.execute("DELETE FROM liv WHERE bibliyotek_id = ?", (bibliyotek_id))
            self.cursor.execute("DELETE FROM bibliyotek WHERE id = ?", (bibliyotek_id,))
            self.conn.commit()
            return True # Retounen True si efase bibliyotèk reyisi
        
    def efase_liv(self, liv_id): #delete book function it doesn't work. 
        self.cursor.execute("DELETE FROM liv WHERE id = ?", (liv_id,))
        #changes = self.conn.total_changes
        self.conn.commit()

        #return changes > 0

#filename: bibliyotek.py


from liv import Liv
from database import Database

class Bibliyotek:
    def __init__(self, non, db):
        self.non = non
        self.db = db
        self.id = db.ajoute_bibliyotek(non)

    def ajoute_liv(self, liv):
        # self.db.ajoute_liv(liv, self.id)
        liv_id = self.db.ajoute_liv(liv, self.id)
        liv.id = liv_id # Mete id a nan objè liv la

    def montre_liv_disponib(self):
        liv_disponib = self.db.get_liv_pa_bibliyotek(self.id)
        if liv_disponib:
            for liv in liv_disponib:
                print(f"Id: {liv.tit}. Tit: {liv.id}, Otè: {liv.otè}")
        else:
            print("Pa gen liv disponib nan bibliyotèk sa a.")
    
    def efase_liv(self, liv_id):
        self.db.efase_liv(liv_id)

and the main.py


from database import Database
from bibliyotek import Bibliyotek
from liv import Liv

def meni_efasman(db, bibliyotek_yo):
    chwa = input("Tape '1' pou w efase yon liv oswa '2' pou w efase yon bibliyotèk: ")

    if chwa == '1':
        print("\nBibliyotèk disponib:")
        for idx, bibliyotek in enumerate(bibliyotek_yo):
            print(f"{idx + 1}. {bibliyotek.non}")
        
        bibliyotek_chwa = int(input("Chwazi bibliyotèk kote ou vle efase liv la (pa nimewo): ")) - 1
        bibliyotek = bibliyotek_yo[bibliyotek_chwa]

        print("\nLiv disponib:")
        liv_yo = db.get_liv_pa_bibliyotek(bibliyotek.id)
        for idx, liv in enumerate(liv_yo):
            print(f"{idx + 1}. {liv.tit} pa {liv.otè}")
        
        liv_chwa = int(input("Chwazi liv ou vle efase a (pa nimewo): ")) - 1
        liv = liv_yo[liv_chwa]

        if db.efase_liv(liv.id):
            print("Liv la efase avèk siksè.")
        else:
            print("Liv la pa efase.")

    elif chwa == '2':
        print("\nBibliyotèk disponib:")
        for idx, bibliyotek in enumerate(bibliyotek_yo):
            print(f"{idx + 1}. {bibliyotek.non}")

        bibliyotek_chwa = int(input("Chwazi bibliytèk ou vle efase a (pa nimewo): ")) - 1
        bibliyotek = bibliyotek_yo[bibliyotek_chwa]

        if not db.efase_bibliyotek(bibliyotek.id):
            print("Bibliyotèk sa a gen liv ladan l toujou. Tanpri efase tout liv yo avan ou efase bibliyotèk la.")
        else:
            print("Bibliyotèk la efase avèk siksè.")



def meni_prensipal():
    db = Database()
    bibliyotek_yo = []

    # Chaje bibliyotèk ki deja egziste yo
    bibliyotek_rows = db.get_bibliyotek_yo()
    for bibliyotek_id, non, in bibliyotek_rows:
        bibliyotek = Bibliyotek(non, db)
        bibliyotek.id = bibliyotek_id
        bibliyotek_yo.append(bibliyotek)

    
    while True:
        print("\n1. Ajoute yon Bibliyotèk")
        print("2. Ajoute yon Liv nan yon Bibliyotèk")
        print("3. Montre Liv nan yon Bibliyotèk")
        print("4. Efase yon liv oswa yon bibliyotèk")
        print("5. Kite Pwogram nan")
        chwa = input("Chwazi yon opsyon: ")

        if chwa == "1":
            non_bibliyotek = input("Antre non bibliyotèk la: ")
            bibliyotek = Bibliyotek(non_bibliyotek, db)
            bibliyotek_yo.append(bibliyotek)
            print(f"Bibliyotèk '{non_bibliyotek}' ajoute avèk siksè.")

        elif chwa == "2":
            if not bibliyotek_yo:
                print("Pa gen bibliyotèk pou ajoute liv. Tanpri ajoute yon bibliyotèk an premye.")
                continue

            for idx, bibliyotek in enumerate(bibliyotek_yo):
                print(f"{idx + 1}. {bibliyotek.non}")
            chwazi_bibliyotek = int(input("Chwazi yon bibliyotèk: ")) - 1

            if 0 <= chwazi_bibliyotek < len(bibliyotek_yo):
                tit = input("Antre tit liv la: ")
                otè = input("Antre non otè liv la: ")
                liv = Liv(tit, otè)
                bibliyotek_yo[chwazi_bibliyotek].ajoute_liv(liv)
                print(f"Liv '{tit}' ajoute nan bibliyotèk '{bibliyotek_yo[chwazi_bibliyotek].non}' avèk siksè.")
            else:
                print("Chwa sa a pa valab.")
        
        elif chwa == "3":
            if not bibliyotek_yo:
                print("Pa gen bibliyotèk pou montre liv. Tanpri ajoute yon bibliyotèk an premye.")
                continue

            for idx, bibliyotek in enumerate(bibliyotek_yo):
                print(f"{idx + 1}. {bibliyotek.non}")
            chwazi_bibliyotek = int(input("Chwazi yon bibliyotèk: ")) - 1

            if 0 <= chwazi_bibliyotek < len(bibliyotek_yo):
                bibliyotek_yo[chwazi_bibliyotek].montre_liv_disponib()
            else:
                print("Chwa sa a pa valab.")

        elif chwa == "4":
            meni_efasman(db, bibliyotek_yo)

        elif chwa == "5":
            print("Mèsi paske w te itilize pwogram nan. Orevwa!")
            break

        else:
            print("Tanpri chwazi yon opsyon valab.")

    db.close()

meni_prensipal()

The efase_liv (delete_book in Haitian) doesn't work but I don't receive any error message. I don't why it does not work. Thank you for helping.


Solution

  • I've made multiple changes to your code to fix the functionality and error handling.

    1. Fixed the montre_liv_disponib method to display the ID and title in the correct order:
    class Bibliyotek:
        def __init__(self, non, db):
            self.non = non
            self.db = db
            self.id = db.ajoute_bibliyotek(non)
    
        def ajoute_liv(self, liv):
            liv_id = self.db.ajoute_liv(liv, self.id)
            liv.id = liv_id
    
        def montre_liv_disponib(self):
            liv_disponib = self.db.get_liv_pa_bibliyotek(self.id)
            if liv_disponib:
                for liv in liv_disponib:
                    print(f"Id: {liv.id}, Tit: {liv.tit}, Otè: {liv.otè}")  # Fixed order
            else:
                print("Pa gen liv disponib nan bibliyotèk sa a.")
        
        def efase_liv(self, liv_id):
            return self.db.efase_liv(liv_id)  # Return the result
    
    1. Updated the get_liv_pa_bibliyotek method to properly create Liv objects with correct parameter order
    def get_liv_pa_bibliyotek(self, bibliyotek_id):
            self.cursor.execute("SELECT id, tit, otè FROM liv WHERE bibliyotek_id = ?", (bibliyotek_id,))
            rows = self.cursor.fetchall()
            return [Liv(tit=row[1], otè=row[2], id=row[0]) for row in rows]  # Fixed order of parameters
    
    
    1. Enhanced the efase_liv method in the Database class to:
    def efase_liv(self, liv_id):
            try:
                self.cursor.execute("SELECT COUNT(*) FROM liv WHERE id = ?", (liv_id,))
                count = self.cursor.fetchone()[0]
                
                if count == 0:
                    return False  # Book doesn't exist
                    
                self.cursor.execute("DELETE FROM liv WHERE id = ?", (liv_id,))
                self.conn.commit()
                return True  # Successfully deleted
            except sqlite3.Error:
                return False  # Error occurred during deletion
    
    1. Improved error handling in the meni_efasman function and added better user feedback messages
    def meni_efasman(db, bibliyotek_yo):
        chwa = input("Tape '1' pou w efase yon liv oswa '2' pou w efase yon bibliyotèk: ")
    
        if chwa == '1':
            print("\nBibliyotèk disponib:")
            for idx, bibliyotek in enumerate(bibliyotek_yo):
                print(f"{idx + 1}. {bibliyotek.non}")
            
            try:
                bibliyotek_chwa = int(input("Chwazi bibliyotèk kote ou vle efase liv la (pa nimewo): ")) - 1
                if bibliyotek_chwa < 0 or bibliyotek_chwa >= len(bibliyotek_yo):
                    print("Nimewo bibliyotèk la pa valab.")
                    return
                    
                bibliyotek = bibliyotek_yo[bibliyotek_chwa]
    
                print("\nLiv disponib:")
                liv_yo = db.get_liv_pa_bibliyotek(bibliyotek.id)
                if not liv_yo:
                    print("Pa gen liv nan bibliyotèk sa a.")
                    return
                    
                for idx, liv in enumerate(liv_yo):
                    print(f"{idx + 1}. {liv.tit} pa {liv.otè} (ID: {liv.id})")
                
                liv_chwa = int(input("Chwazi liv ou vle efase a (pa nimewo): ")) - 1
                if liv_chwa < 0 or liv_chwa >= len(liv_yo):
                    print("Nimewo liv la pa valab.")
                    return
                    
                liv = liv_yo[liv_chwa]
    
                if bibliyotek.efase_liv(liv.id):
                    print("Liv la efase avèk siksè.")
                else:
                    print("Liv la pa t ka efase. Tanpri eseye ankò.")
                    
            except ValueError:
                print("Tanpri antre yon nimewo valab.")
                return
    
        elif chwa == '2':
            # ... (keep the rest of the function the same)
    

    The main reasons why your delete functionality wasn't working: