Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable table name in sqlite

Question: Is it possible to use a variable as your table name without having to use string constructors to do so?


Info:

I'm working on a project right now that catalogs data from a star simulation of mine. To do so I'm loading all the data into a sqlite database. It's working pretty well, but I've decided to add a lot more flexibility, efficiency, and usability to my db. I plan on later adding planetoids to the simulation, and wanted to have a table for each star. This way I wouldn't have to query a table of 20m some planetoids for the 1-4k in each solar system.

I've been told using string constructors is bad because it leaves me vulnerable to a SQL injection attack. While that isn't a big deal here as I'm the only person with access to these dbs, I would like to follow best practices. And also this way if I do a project with a similar situation where it is open to the public, I know what to do.

Currently I'm doing this:

cursor.execute("CREATE TABLE StarFrame"+self.name+" (etc etc)")

This works, but I would like to do something more like:

cursor.execute("CREATE TABLE StarFrame(?) (etc etc)",self.name)

though I understand that this would probably be impossible. though I would settle for something like

cursor.execute("CREATE TABLE (?) (etc etc)",self.name)

If this is not at all possible, I'll accept that answer, but if anyone knows a way to do this, do tell. :)

I'm coding in python.

like image 440
Narcolapser Avatar asked Jul 14 '10 14:07

Narcolapser


People also ask

How do you name a table in SQLite?

To rename a table, the SQLite ALTER TABLE syntax is: ALTER TABLE table_name RENAME TO new_table_name; table_name. The table to rename.

Can you declare variables in SQLite?

SQLite doesn't support native variable syntax, but you can achieve virtually the same using an in-memory temp table.

How do you describe a table in SQLite?

Each SQLite database has a solitary “schema table” that holds the schema for that database. Database uses the schema and is a depiction of the entirety of different tables, lists, triggers, and views that are contained inside the database.

How do I create a SQLite table in Python?

SQLite Python: Creating Tables First, create a Connection object using the connect() function of the sqlite3 module. Second, create a Cursor object by calling the cursor() method of the Connection object. Third, pass the CREATE TABLE statement to the execute() method of the Cursor object and execute this method.


4 Answers

Unfortunately, tables can't be the target of parameter substitution (I didn't find any definitive source, but I have seen it on a few web forums).

If you are worried about injection (you probably should be), you can write a function that cleans the string before passing it. Since you are looking for just a table name, you should be safe just accepting alphanumerics, stripping out all punctuation, such as )(][;, and whitespace. Basically, just keep A-Z a-z 0-9.

def scrub(table_name):     return ''.join( chr for chr in table_name if chr.isalnum() )  scrub('); drop tables --')  # returns 'droptables' 
like image 197
Donald Miner Avatar answered Sep 22 '22 10:09

Donald Miner


For people searching for a way to make the table as a variable, I got this from another reply to same question here:

It said the following and it works. It's all quoted from mhawke:

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 
like image 42
jubibanna Avatar answered Sep 23 '22 10:09

jubibanna


I wouldn't separate the data into more than one table. If you create an index on the star column, you won't have any problem efficiently accessing the data.

like image 23
Ned Batchelder Avatar answered Sep 19 '22 10:09

Ned Batchelder


Try with string formatting:

sql_cmd = '''CREATE TABLE {}(id, column1, column2, column2)'''.format(
            'table_name')
db.execute(sql_cmd)

Replace 'table_name' with your desire.

like image 33
Windows Eight Avatar answered Sep 19 '22 10:09

Windows Eight