How to create table dynamically from user input? [duplicate] - python

This question already has answers here:
SQLite: Why can't parameters be used to set an identifier?
(3 answers)
Closed 3 months ago.
I am creating a wishlist app using Tkinter and sqlite3. I want the user to be able to create tables in database by imputing names. For that I connected a button to this function:
def create_table(table_name):
connection = sql.connect(f'{directory}\main.sqlite')
cursor = connection.cursor()
cursor.execute("CREATE TABLE ? (name TEXT, price REAL, url TEXT)",(table_name,))
connection.close()
This doesn't work and I get:
cursor.execute("create table ? (name text, price real, url text)",(table_name,))
sqlite3.OperationalError: near "?": syntax error
Is it possible to do string formatting in CREATE TABLE? I'd rather create separate tables than one with additional column for id of items. I don't want to use f-string as it can be an issue if user inputs commands instead of a name.

Nope, this cannot be done. A table name cannot act as a dynamic parameter from SQLite's point of view. You will need to do something like this:
f'CREATE TABLE {table_name} (name TEXT, price REAL, url TEXT)'
But first you will need to validate the user input for table_name. Which shouldn't be a problem if you want to limit the allowed characters to (for example) only 1+ English letters and 0+ underscores. You might also want to validate the table name length and uniqueness somehow.

Related

How to insert variable to sql table in python if variable is not already in table? [duplicate]

This question already has answers here:
SQLite INSERT - ON DUPLICATE KEY UPDATE (UPSERT)
(5 answers)
Closed 6 months ago.
Im having a problem with my sqlite database in my python program. I'm trying to create a table that will hold records of players score. Player name is saved as variable "val" and that variable is used in sql code. Also if the player is already in my table I don't want to create duplicate.
My problem is that if I don't use WHERE {v}... it all works, but the moment i try to prevent table from creating duplicates it gives me an OperationalError: near "WHERE": syntax error.
Im quite new to sql so it's hard for me to find what i'm doing wrong. I used (?) and format and as long as i don't use WHERE it's fine. How can I make sure that my variable (player name) from outside of sql code is not in my table so i can insert it?
val = "PlayerName"
cur.execute( """
INSERT INTO Table (player_name)
VALUES {v}
WHERE {v} NOT IN (
SELECT player_name FROM Table)""".format(v = val))
Ok, it works now. My main problem was that i tried to use commands from MySQL instead of sqlite. My code that worked:
cur.execute( """INSERT INTO Table (player_name)
VALUES (?)
ON CONFLICT(player_name) DO UPDATE SET player_name= player_name""",(val) )
Edit: Final version without player_name = player_name workaround:
cur.execute( """INSERT OR IGNORE INTO Table (player_name) VALUES (?)""",(val) )

Querying SQLite Database for specific cell [duplicate]

This question already has answers here:
sqlite3.OperationalError: no such column - but I'm not asking for a column?
(2 answers)
Closed 2 years ago.
Forgive me if this is a basic question, I'm learning on my own and having some trouble. I have built a database with SQLite and am trying to write something that can display the 'description' of an entry when the name is entered into an entry box.
record_id = call_field.get()
# Query the database
c.execute("SELECT name, abbr, description FROM TQ_QUICKTEXT WHERE name =" + record_id)
records = c.fetchall()
# Loop through results
for record in records:
display.insert(1.0, record[2])
When I type the name of the entry that has been put into the database, an error is returned saying there is no column with that name. However, when I type the actual word 'name' into the entry box and run the function every single description entry is returned. If someone wouldn't mind pointing out where I've made mistakes it would be greatly appreciated. Thank you in advance.
The SELECT statement that is executed currently looks like this:
SELECT name, abbr, description FROM TQ_QUICKTEXT WHERE name = something (where something is the value of record_id)
Because there are no quotes around the value of record_id, it thinks it is a column name, not text. This is why when you try the name of a record, you get an error because that is not a column name, but name works, because it is the name of a column.
Adding quotes will fix the problem, but the database is vulnerable to SQL injection.
It is good security practise to parameterise SQL queries to prevent this. This is done by using ? in place of parameters and then passing a tuple of parameters to the execute function. This protects you from SQL injection.
After these changes, the c.execute statment should look like this:
c.execute("SELECT name, abbr, description FROM TQ_QUICKTEXT WHERE name = ?", (record_id,))

Can I perform SQL query in table based on user input? [duplicate]

This question already has answers here:
Variable table name in sqlite
(9 answers)
Closed 2 years ago.
So, I am new to Stackoverflow and I hope I'm writing this question well. So I'm trying to choose a table from my database (that contains 5 tables) based on user input in python. However I'm not quite sure how to do it. Here is the code:
user_input = "table1"
db.execute("SELECT number FROM (?) WHERE person = 1;")
I'm searching for a way if it is possible. Anyway any help would be appreciated.
Well, after some verifications in order to forbid SQL injections, the easiest way is to format the query string with the user input.
db.execute ("SELECT * FROM MyTable WHERE person = {};".format(user_input))
And the content of user_input would be placed on the curly brackets.
It's not very clear on how you're getting user input, though.

MySQL Python - VARCHAR issue with alfanumerical values [duplicate]

This question already has answers here:
When to use single quotes, double quotes, and backticks in MySQL
(13 answers)
Closed 5 years ago.
I'm trying to make an access control system based on pincode entry. I'm having issues on how to check if the pincode entered is present in the MySQL database.
Below snippet works, it asks for the pincode, and can successfully parse it with the database when the pincode only contains numbers.
pin_inp = raw_input("Enter PIN: ")
cursor.execute("SELECT COUNT(1) FROM members WHERE pincode = " + pin_inp + ";")
But I would like to have alphanumerical pincodes though. I thought I could just create the pincode column as VARCHAR and enter alphanumerical pincodes, but then it will not successfully parse with the database. With an alphanumerical entry I get this error:
_mysql_exceptions.OperationalError: (1054, "Unknown column '7988DB' in 'where clause'")
So I have a few rows in the members table for testing, some with numerical values in column pincode, some with alphanumerical values. When I run above code, the numerical entries are OK, but the alphanumerical values throw the 1054 error.
When you use numerical values, you just enter them like you did, but when you used alphanumerical values, you must surround them with apostrophes like this'my value'. So change your code to:
cursor.execute("SELECT COUNT(1) FROM members WHERE pincode = '" + pin_inp + "';")
However, be careful here. This code will be open to SQL injection since the pin_inp is coming from user's input. You either have to validate it, or better use a parameterized SQL statement.

How to use variable for SQLite table name [duplicate]

This question already has answers here:
Variable table name in sqlite
(9 answers)
Closed 6 years ago.
I have a program where the user can select what table they want to modify in SQLite. I store the selection in a variable called table, then try and select everything from that table
c.execute('SELECT * FROM ?', (table,))
The program gets stuck at the question mark. It says:
"Sqlite3.OperationalError: near "?": syntax error"
What am I doing wrong?
You can't use parameter substitution for the table name. You need to add the table name to the query string yourself. Something like this:
query = 'SELECT * FROM {}'.format(table)
c.execute(query)
One thing to be mindful of is the source of the value for the table name. If that comes from an untrusted source, e.g. a user, then you need to validate the table name to avoid potential SQL injection attacks. One way might be to construct a parameterised query that looks up the table name from the DB catalogue:
import sqlite3
def exists_table(db, name):
query = "SELECT 1 FROM sqlite_master WHERE type='table' and name = ?"
return db.execute(query, (name,)).fetchone() is not None

Categories