Every time I try to save data to my contacts database I get an error. The script runs fine, but when it come to clicking save I get this error.

Traceback (most recent call last):
File "C:\Users\Panic\Desktop\EminentGeekTechnology\Looking For Who\addnew.py", line 71, in OnSave
self.database.execute('INSERT INTO contacts (fname) VALUES (null,?),' [fname])
AttributeError: 'contact' object has no attribute 'database'

#Importing modules

import os
import wx
import sqlite3
import Database








#This will create a class

class contact(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, 'Add Contact', size = (455,170))
        panel = wx.Panel(self, -1)

#This will center the Frame

        self.Centre()
       
       
        

#This will create input fields for the user 
          
        fnameLabel = wx.StaticText(panel, -1, "        First Name:")
        fname = wx.TextCtrl(panel, -1, "")
        fnameLabel.SetFont(wx.Font (10, wx.SWISS, wx.NORMAL, wx.BOLD))
        fname.SetInsertionPoint(0)

        lnameLabel = wx.StaticText(panel, -1, "  Last Name:")
        lname = wx.TextCtrl(panel, -1, "")
        lnameLabel.SetFont(wx.Font (10, wx.SWISS, wx.NORMAL, wx.BOLD))
        
        phoneLabel = wx.StaticText(panel, -1, "               Phone:")
        phone = wx.TextCtrl(panel, -1, "")
        phoneLabel.SetFont(wx.Font (10, wx.SWISS, wx.NORMAL, wx.BOLD))

        addressLabel = wx.StaticText(panel, -1, "      Address:")
        address = wx.TextCtrl(panel, -1, "")
        addressLabel.SetFont(wx.Font (10, wx.SWISS, wx.NORMAL, wx.BOLD))

        emailLabel = wx.StaticText(panel, -1, "                Email:")
        email = wx.TextCtrl(panel, -1, "")
        emailLabel.SetFont(wx.Font (10, wx.SWISS, wx.NORMAL, wx.BOLD))

    
#This will size the fields

        sizer = wx.FlexGridSizer(cols = 4, hgap = 6, vgap = 6)
        sizer.AddMany([fnameLabel, fname, lnameLabel, lname, phoneLabel, phone, addressLabel, address, emailLabel, email,])
        panel.SetSizer(sizer)

        save = wx.Button(panel, label='Save',pos=(150, 90), size=(80, 25))
        close = wx.Button(panel, label='Close',pos=(250, 90), size=(80, 25))

        save.Bind(wx.EVT_BUTTON, self.OnSave, save)
        close.Bind(wx.EVT_BUTTON, self.OnClose, close)

    def OnSave(self, event):
        dlg = wx.MessageBox("Are you sure you want to save contact?", 'Message', wx.YES_NO | wx.ICON_QUESTION)
        

        if (dlg == wx.YES):
            connection = sqlite3.connect('contacts.db')
            self.database.execute('INSERT INTO contacts (fname) VALUES (null,?),' [fname])
            self.database.execute('INSERT INTO contacts (lname) VALUES (null,?),' [lname])
            self.database.execute('INSERT INTO contacts (phonenumber) VALUES (null,?),' [phone])
            self.database.execute('INSERT INTO contacts (address) VALUES (null,?),' [address])
            self.database.execute('INSERT INTO contacts (email) VALUES (null,?),' [email])
            self.connection.commit()
            database.close()
            if (dlg == wx.NO):
                self.Destroy()
        else:
            return

    def OnClose(self, event):
        dlg = wx.MessageBox("Are you sure you want to cancel?", 'Message', wx.YES_NO | wx.ICON_QUESTION)

        if (dlg == wx.YES):
            self.Destroy()
        else:
            return           
        
            



        
if __name__ == '__main__':
    myApp = wx.App()
    frame = contact()
    frame.Show()
    myApp.MainLoop()

Recommended Answers

All 18 Replies

self.database.execute('INSERT INTO contacts (fname) VALUES (null,?),' [fname])
AttributeError: 'contact' object has no attribute 'database'

It means that you have not declared "self.database" anywhere in your program, and the interpreter does not know if it is a variable, file pointer, another class, etc.

It means that you have not declared "self.database" anywhere in your program, and the interpreter does not know if it is a variable, file pointer, another class, etc.

Thank you. I'll see if I can fix it.

I cannot read your mind but I think the line missing is :

self.database = connection.cursor()

Also I see in line 76
"self.connection.commit()" but I cannot see where self.connection is defined.

I cannot read your mind but I think the line missing is :

self.database = connection.cursor()

Also I see in line 76
"self.connection.commit()" but I cannot see where self.connection is defined.

It's defined in a external file called Database.py. That is the reason I imported Database at the top. Do you want to see that file. I haven't fixed my problem yet. More help would be greatly appreciated. Thanks!

It's defined in a external file called Database.py. That is the reason I imported Database at the top. Do you want to see that file. I haven't fixed my problem yet. More help would be greatly appreciated. Thanks!

Post the code. You have to access the variable from the class in Database.py It would roughly be something along the lines of
DB = Database.database() ## create instance of database class
self.database = DB.connection.cursor()

Post the code. You have to access the variable from the class in Database.py It would roughly be something along the lines of
DB = Database.database() ## create instance of database class
self.database = DB.connection.cursor()

#Importing sqlite3
import sqlite3
import addnew

#Creating a connection to the database.
connection = sqlite3.connect('contacts.db')

#Creating a cursor object to interact with the databae
db = connection.cursor()

#creating tables
db.execute("CREATE TABLE IF NOT EXISTS contacts (fname VARCHAR, lname VARCHAR NOT NULL PRIMARY KEY, phonenumber VARCHAR, address VARCHAR, email VARCHAR)")

connection.commit()
db.close()

where do you get self.database?
I cannot see it in this code either!

If you didn't close the database
connection.commit()
db.close()
you sould be able to access it via Database.db from the second program so try substituting that for self.database and see if it works, or just use
self.database = Database.db

If you didn't close the database
connection.commit()
db.close()
you sould be able to access it via Database.db from the second program so try substituting that for self.database and see if it works, or just use
self.database = Database.db

There you are! He is trying to call self.database which is'nt defined anywhere. This should at least work

Thank you all for your help. I will see if it works.

Your advice help me fix the first problem, now I get a NameError after I run the script and click save.

Traceback (most recent call last):
File "C:\Users\Panic\Desktop\EminentGeekTechnology\Looking For Who\addnew.py", line 77, in OnSave
self.database.execute('INSERT INTO contacts (fname) VALUES (null,?),' [fname])
NameError: global name 'fname' is not defined

#Importing modules

import os
import wx
import sqlite3
import Database









#This will create a class

class contact(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, 'Add Contact', size = (455,170))
        panel = wx.Panel(self, -1)

#This will center the Frame

        self.Centre()

        
       
       
        

#This will create input fields for the user 
          
        fnameLabel = wx.StaticText(panel, -1, "        First Name:")
        fname = wx.TextCtrl(panel, -1, "")
        fnameLabel.SetFont(wx.Font (10, wx.SWISS, wx.NORMAL, wx.BOLD))
        fname.SetInsertionPoint(0)

        lnameLabel = wx.StaticText(panel, -1, "  Last Name:")
        lname = wx.TextCtrl(panel, -1, "")
        lnameLabel.SetFont(wx.Font (10, wx.SWISS, wx.NORMAL, wx.BOLD))
        
        phoneLabel = wx.StaticText(panel, -1, "               Phone:")
        phone = wx.TextCtrl(panel, -1, "")
        phoneLabel.SetFont(wx.Font (10, wx.SWISS, wx.NORMAL, wx.BOLD))

        addressLabel = wx.StaticText(panel, -1, "      Address:")
        address = wx.TextCtrl(panel, -1, "")
        addressLabel.SetFont(wx.Font (10, wx.SWISS, wx.NORMAL, wx.BOLD))

        emailLabel = wx.StaticText(panel, -1, "                Email:")
        email = wx.TextCtrl(panel, -1, "")
        emailLabel.SetFont(wx.Font (10, wx.SWISS, wx.NORMAL, wx.BOLD))

    
#This will size the fields

        sizer = wx.FlexGridSizer(cols = 4, hgap = 6, vgap = 6)
        sizer.AddMany([fnameLabel, fname, lnameLabel, lname, phoneLabel, phone, addressLabel, address, emailLabel, email,])
        panel.SetSizer(sizer)

        save = wx.Button(panel, label='Save',pos=(150, 90), size=(80, 25))
        close = wx.Button(panel, label='Close',pos=(250, 90), size=(80, 25))

        save.Bind(wx.EVT_BUTTON, self.OnSave, save)
        close.Bind(wx.EVT_BUTTON, self.OnClose, close)

        self.database = Database.db

        
    def OnSave(self, event):
        dlg = wx.MessageBox("Are you sure you want to save contact?", 'Message', wx.YES_NO | wx.ICON_QUESTION)
        

        if (dlg == wx.YES):
            connection = sqlite3.connect('contacts.db')
            self.database.execute('INSERT INTO contacts (fname) VALUES (null,?),' [fname])
            self.database.execute('INSERT INTO contacts (lname) VALUES (null,?),' [lname])
            self.database.execute('INSERT INTO contacts (phonenumber) VALUES (null,?),' [phone])
            self.database.execute('INSERT INTO contacts (address) VALUES (null,?),' [address])
            self.database.execute('INSERT INTO contacts (email) VALUES (null,?),' [email])
            connection.commit()
            database.close()
            if (dlg == wx.NO):
                self.Destroy()
        else:
            return

    def OnClose(self, event):
        dlg = wx.MessageBox("Are you sure you want to cancel?", 'Message', wx.YES_NO | wx.ICON_QUESTION)

        if (dlg == wx.YES):
            self.Destroy()
        else:
            return           
        
            



        
if __name__ == '__main__':
    myApp = wx.App()
    frame = contact()
    frame.Show()
    myApp.MainLoop()

Still need help with this.

replace fname throughout with self.fname
That is because self.fname is accessible throughout the class

try and see what happens

replace fname throughout with self.fname
That is because self.fname is accessible throughout the class

try and see what happens

I tried that and I get the same error, I am probably doing something wrong.

Traceback (most recent call last):
File "C:\Users\Panic\Desktop\EminentGeekTechnology\Looking For Who\addnew.py", line 79, in OnSave
self.database.execute('INSERT INTO contacts (fname) VALUES (null,?),' [fname])
NameError: global name 'fname' is not defined

#Importing modules

import os
import wx
import sqlite3
import Database









#This will create a class

class contact(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, 'Add Contact', size = (455,170))
        panel = wx.Panel(self, -1)

#This will center the Frame

        self.Centre()

        
       
       
        

#This will create input fields for the user 
          
        fnameLabel = wx.StaticText(panel, -1, "        First Name:")
        self.fname = wx.TextCtrl(panel, -1, "")
        fnameLabel.SetFont(wx.Font (10, wx.SWISS, wx.NORMAL, wx.BOLD))
        self.fname.SetInsertionPoint(0)

        lnameLabel = wx.StaticText(panel, -1, "  Last Name:")
        self.lname = wx.TextCtrl(panel, -1, "")
        lnameLabel.SetFont(wx.Font (10, wx.SWISS, wx.NORMAL, wx.BOLD))
        
        phoneLabel = wx.StaticText(panel, -1, "               Phone:")
        self.phone = wx.TextCtrl(panel, -1, "")
        phoneLabel.SetFont(wx.Font (10, wx.SWISS, wx.NORMAL, wx.BOLD))

        addressLabel = wx.StaticText(panel, -1, "      Address:")
        self.address = wx.TextCtrl(panel, -1, "")
        addressLabel.SetFont(wx.Font (10, wx.SWISS, wx.NORMAL, wx.BOLD))

        emailLabel = wx.StaticText(panel, -1, "                Email:")
        self.email = wx.TextCtrl(panel, -1, "")
        emailLabel.SetFont(wx.Font (10, wx.SWISS, wx.NORMAL, wx.BOLD))

    
#This will size the fields

        sizer = wx.FlexGridSizer(cols = 4, hgap = 6, vgap = 6)
        sizer.AddMany([fnameLabel, self.fname, lnameLabel, self.lname, phoneLabel, self.phone, addressLabel, self.address, emailLabel, self.email,])
        panel.SetSizer(sizer)

        save = wx.Button(panel, label='Save',pos=(150, 90), size=(80, 25))
        close = wx.Button(panel, label='Close',pos=(250, 90), size=(80, 25))

        save.Bind(wx.EVT_BUTTON, self.OnSave, save)
        close.Bind(wx.EVT_BUTTON, self.OnClose, close)

        self.database = Database.db
        
        

        
    def OnSave(self, event):
        dlg = wx.MessageBox("Are you sure you want to save contact?", 'Message', wx.YES_NO | wx.ICON_QUESTION)
        

        if (dlg == wx.YES):
            connection = sqlite3.connect('contacts.db')
            self.database.execute('INSERT INTO contacts (fname) VALUES (null,?),' [fname])
            self.database.execute('INSERT INTO contacts (lname) VALUES (null,?),' [lname])
            self.database.execute('INSERT INTO contacts (phonenumber) VALUES (null,?),' [phone])
            self.database.execute('INSERT INTO contacts (address) VALUES (null,?),' [address])
            self.database.execute('INSERT INTO contacts (email) VALUES (null,?),' [email])
            connection.commit()
            database.close()
            if (dlg == wx.NO):
                self.Destroy()
        else:
            return

    def OnClose(self, event):
        dlg = wx.MessageBox("Are you sure you want to cancel?", 'Message', wx.YES_NO | wx.ICON_QUESTION)

        if (dlg == wx.YES):
            self.Destroy()
        else:
            return           
        
            



        
if __name__ == '__main__':
    myApp = wx.App()
    frame = contact()
    frame.Show()
    myApp.MainLoop()

You want to keep all of the sqlite stuff in Database.py and call the add, change, delete functions from the WX program. An example using addition.

import sqlite3
##import addnew

class DBClass:
    def __init__(self):
        #Creating a connection to the database.
        self.connection = sqlite3.connect('contacts.db')

        #Creating a cursor object to interact with the databae
        self.db = self.connection.cursor()

        #creating tables
        self.db.execute("CREATE TABLE IF NOT EXISTS contacts (fname VARCHAR, lname VARCHAR NOT NULL PRIMARY KEY, phonenumber VARCHAR, address VARCHAR, email VARCHAR)")
        self.connection.commit()

    ##................................................................................................
    def __del__(self):
        self.db.close()

    ##................................................................................................
    def add_record(self, add_tuple):
        """ receives a tuple and adds it to the database
            does not do any checking of data, so will add
            duplicate records, or malformed data
            to call this: self.database.add_record(tuple_to_add)
        """
        self.db.execute("insert into contacts (fname, lname, phonenumber, address, email) values (?, ?, ?, ?, ?)", add_tuple)
        self.connection.commit()

    ##................................................................................................
    def print_all(self):
        """ Retrieves all rows as a sequence and prints that sequence:
        """
        self.db.execute("select * from contacts")
        for rec in self.db.fetchall():
            print rec

##====================================================================
## simulate calling this from the wxpython program
##====================================================================
class WXProgram:
    def __init__(self):
        self.database = DBClass()
        f_name = "abc.txt"
        last_name = "Smith"
        phone="555-5555"
        address="123 Main St."
        email="Smith@gmail.com"
        self.database.add_record( (f_name, last_name, phone, address, email) )

        f_name = "def.txt"
        last_name = "Jones"
        phone="555-1111"
        address="345 First St."
        email="Jones@gmail.com"
        to_add = (f_name, last_name, phone, address, email)
        self.database.add_record(to_add)

        print "printing records"
        self.database.print_all()

        ## we don't have to explictly close the class, but it can be
        ## done by assigning self.database some other value
        self.database = None

##====================================================================
if __name__ == "__main__":
   WX=WXProgram()

Well with all your help and the help of this website here. I re-did my add script and finally got it to work. Thanks

Now I am off to do a script that deletes, searches, and edits.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.