Python Forum

Full Version: Sqlite3 DELETE question
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have been reading a number of threads on how to accomplish this but for some reason it is not working.
I need to delete a specific row from a database. I am using a string variable from an entry widget to find the file I want to delete. The entry widget data is stored as variable Snippet_Name and the column to query is also named Snippet_Name.
The database has 7 columns but I am only using the 1 column for the query to find the file to delete the row. I have tried variations of DELETE with no success, even after reading countless threads and tutorials and looking at various examples (all use rowed).
I can delete the file using the rowid but if there is multiple files over time a user would not know the rowed so it needs to be looked up by the name entered in the Entry widget.
I am clearly missing something that I can't seem to find.

The code being used is:
def delete_code():
    try:
        snippetname = Snippet_Name.get()
        sql_delete_query = ('DELETE FROM Code WHERE Snippet_Name = "?"', (snippetname))
        c.execute(sql_delete_query)
        conn.commit()

    except:
        messagebox.showerror('PYSnippet', 'Failed to delete record')
If your going to be doing deletes by name, might want to ask the question, is this a multi-user program? Or is just one user going to be using it? Are there going to be multiple categories with the same name you are trying to delete. I've been experimenting with sqlite and I can come up with to help.
print sql_delete_query and try to run a select using everything after delete from on sqlite3. It may not be formatted properly
You should be able to delete with the name. I agree with larz60+. Check the formating.
Results of my test. It's from command line though. Are you opening the database before editing?
Output:
sqlite> select * from test; 1|this name 2|my name 3|my name sqlite> sqlite> delete from test where name = 'my name'; sqlite> select * from test; 1|this name sqlite>
Larz06+, the program is for single user. Each saved entry is a unique name and the database is queried before saving new data to prevent duplicate names, so only 1 piece will ever have the name it is looking to find or when deleting it.
Formatting in my delete query may well be the problem.

menator01, yes the database has been opened prior to running this query. I'm old but not always that forgetful lol.
Using the example you did I have also been able to get it to work prior however for what ever reason I seem to be overlooking something in my current query.

Ok so a brief summary:
The table "Code" contains 7 columns in total.
User inputs the name of a file in the Entry widget(its variable is Snippet_Name).
User clicks the delete button.
Button sends to def statement where the query is done.
Query finds the name of the file in the database column named Snippet_Name and deletes that file.
The entry widget variable and column name share the same name, perhaps I should really change that.

The database has 2 tables so calling the correct table "Code" is done as shown within the line:
sql_delete_query = ('DELETE FROM Code
Second, I use the WHERE condition to look in the column Snippet_Name and placeholder.
WHERE Snippet_Name = ?'
Third, I used the assigned variable that contains the stored name of the file name from the Entry widget (snippetname=Snippet_Name.get) to search for the correct row in the table "Code" and column "Snippet_Name" so that row containing the name in the variable can be deleted.
,(snippetname))
Maybe I desperately need sleep because clearly I am missing something here.
Have you tried without using the placeholder?
sql_delete_query = ('DELETE FROM Code WHERE Snippet_Name = "?"', (snippetname))

#python3.8
sql_delete_query = (f'DELETE FROM Code WHERE Snippet_Name = "{snippetname}"')

#older version
sql_delete_query = ('DELETE FROM Code WHERE Snippet_Name = "' + snippetname + '"')
try
sql_delete_query = 'DELETE FROM Code WHERE Snippet_Name = "?"'
c.execute(sql_delete_query, (snippetname,))
Note the comma, without it, it's not a tuple.

@menator - not using placeholders (i.e. parametrized queries) represents security risk and opens possibility for sql injection
I had tried this format as well but I just attempted it again and got the following error.
Error:
File "C:\Users\ve3je\Documents\Python Projects\PYSnippet\PYSnippet.py", line 334, in delete_code c.execute(sql_delete_query, (snippetname,)) sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 0, and there are 1 supplied.

Ok, I found the problem with the error I received. To correct the issue I needed to remove the quotes from the "?". Once the quotations were removed it is works correctly.

Thank you once again buran.