How to use variable for SQLite table name [duplicate] - python

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

Related

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

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.

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,))

Python mysql parameters and load data command [duplicate]

This question already has an answer here:
Python sqlite3 parameterized drop table
(1 answer)
Closed 5 years ago.
I'm trying to use a variable for a table name. I get the error "... near ''myTable'' at line 1
I must not be escaping this right. The double '' in the error seems to be a clue, but I don't get it.
db = MySQLdb.connect("localhost","user","pw","database" )
table = "myTable"
def geno_order(db, table):
cursor = db.cursor() # prepare a cursor object using cursor() method
sql = "SELECT * FROM %s"
cursor.execute(sql, table)
results = cursor.fetchall()
You can't use a parameter for the table name in the execute call. You'll need to use normal Python string interpolation for that:
sql = "SELECT * FROM %s" % table
cursor.execute(sql)
Naturally, you'll need to be extra careful if the table name is coming from user input. To mitigate SQL injection, validate the table name against a list of valid names.

Check if sql table exists in python [duplicate]

This question already has answers here:
How to test if a table already exists?
(4 answers)
Closed 6 years ago.
I am making a python application for a voting system. I am using sqlite3 to create a database which is stored locally on the user's machine.
I need a way to check if a table exists or not because the tables need to get created on each user's database file when they run the application but if the application is run when the tables exist and I just have a statement creating the tables it will run an error because the table already exists.
Here is some simplified sample code
conn = sqlite3.connect('firefight')
c = conn.cursor()
if table 'info' exists:
#do nothing
else:
c.execute("CREATE TABLE info(PRIMARY KEY id int, username text, password text)")
I think there are two options here. First, SQLite has a statement which would create the table only if it does not exist:
CREATE TABLE IF NOT EXISTS info (PRIMARY KEY id int, username text, password text)
But if you want a more database generic way to handle this, you could simply execute a regular CREATE TABLE statement and then handle the exception in Python.
You can execute this SQL:
select count(*) from sqlite_master where type='table' and name='table name'
if you get 1, the table exists, otherwise not exists.

Python MySQLdb execute table variable [duplicate]

This question already has an answer here:
Python sqlite3 parameterized drop table
(1 answer)
Closed 5 years ago.
I'm trying to use a variable for a table name. I get the error "... near ''myTable'' at line 1
I must not be escaping this right. The double '' in the error seems to be a clue, but I don't get it.
db = MySQLdb.connect("localhost","user","pw","database" )
table = "myTable"
def geno_order(db, table):
cursor = db.cursor() # prepare a cursor object using cursor() method
sql = "SELECT * FROM %s"
cursor.execute(sql, table)
results = cursor.fetchall()
You can't use a parameter for the table name in the execute call. You'll need to use normal Python string interpolation for that:
sql = "SELECT * FROM %s" % table
cursor.execute(sql)
Naturally, you'll need to be extra careful if the table name is coming from user input. To mitigate SQL injection, validate the table name against a list of valid names.

Categories