Python Forum

Full Version: Button to add data to database and listbox
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello. I am creating a database that holds info on a person's name and phone number. The names are displayed in a listbox and when the user clicked a name a message box appears that displays their info.

There are also 2 entry boxes, one to input a new name and one to input a new phone number. Then the user clicks the 'add' button and it should update the listbox display and database. But I can't get my 'add' button to work. When I run the program I get the error:
Error:
FOREIGN KEY constraint failed
I don't understand why I get this error. Can you please help me? Here is my code:

    def create_db(self):
        conn = None
        try:
            conn = sqlite3.connect('phonebook.db')
            cur = conn.cursor()

            cur.execute('PRAGMA foreign_keys=ON')

            # add phone table
            cur.execute('DROP TABLE IF EXISTS Phones')
            cur.execute('''CREATE TABLE Phones (PhoneID INTEGER PRIMARY KEY NOT NULL,
                PhoneNumber TEXT)''')

            cur.execute('DROP TABLE IF EXISTS Names')
            cur.execute('''CREATE TABLE Names (NameID INTEGER PRIMARY KEY NOT NULL,
                Name TEXT,
                PhoneID TEXT,
                FOREIGN KEY(PhoneID) REFERENCES Phones(PhoneID))''')

            # add rows to Phones table
            cur.execute('''INSERT INTO Phones(PhoneNumber)
                VALUES ("555-1212"),
                ("555-0101"),
                ("555-9090"),
                ("333-1234"),
                ("555-2345")''')

            # add row to Names table
            cur.execute('''INSERT INTO Names (Name, PhoneID)
                VALUES ("Jason Lee", 1),
                ("Amanda Green", 2),
                ("Jenna Jacobs", 3),
                ("Alfredo Greer", 4),
                ("Jules Landis", 5)''')

            conn.commit()
        except sqlite3.Error as err:
            print(err)
        finally:
            if conn != None:
                conn.close()
# create entry field
    def __build_entries(self):
        self.name_entry = tkinter.Entry(self.main_window,
                                        width=15)
        self.phone_entry = tkinter.Entry(self.main_window,
                                         width=10)

        name = self.name_entry.get()
        phone = self.phone_entry.get()
        conn = None
        try:
            conn = sqlite3.connect('phonebook.db')
            cur = conn.cursor()
            cur.execute('''INSERT INTO Names (Name, PhoneID)
                        VALUES (?, ?)''',
                        (name, phone))

            conn.commit()
        except sqlite3.Error as err:
            print(err)
        finally:
            if conn != None:
                conn.close()
        self.add_button = tkinter.Button(self.main_window,
                                         text='add',
                                         command=self.__populate_listbox())

        self.name_entry.pack(side='left')
        self.phone_entry.pack(side='left')
        self.add_button.pack(side='left')
# get list from database
    def __get_phones(self):
        name_list = []
        conn = None
        try:
            conn = sqlite3.connect('phonebook.db')
            cur = conn.cursor()

            cur.execute('SELECT Name from Names')
            name_list = [n[0] for n in cur.fetchall()]

        except sqlite3.Error as err:
            tkinter.messagebox.showinfo('Database error:', err)
        finally:
            if conn != None:
                conn.close()
        return name_list

    # fill listbox with database list
    def __populate_listbox(self):
        for name in self.__get_phones():
            emp_list = self.phone_listbox.get(0, tkinter.END)
            if name not in emp_list:
                self.phone_listbox.insert(tkinter.END, name)
Please show complete, unaltered error traceback.
The snippet you show could apply to any of the SQL statements in your code.