sqlite中的variables表名
问题:是否可以使用variables作为表名而不必使用string构造函数呢?
信息:
我现在正在开发一个项目,从一个明星模拟我的数据目录。 为此,我将所有的数据加载到一个sqlite数据库。 它工作得很好,但是我决定为我的db增加更多的灵活性,效率和可用性。 我打算在后来的模拟中添加飞行器,并且想要为每个星星制作一个表格。 这样我就不必在每个太阳系里查询一个20米的桌子了。
我已经被告知使用string构造函数是不好的,因为它使我容易受到SQL注入攻击。 虽然这不是什么大问题,因为我是唯一能够访问这些数据库的人,所以我想遵循最佳实践。 而且这样一来,如果我做一个类似的项目向公众开放,我知道该怎么做。
目前我正在这样做:
cursor.execute("CREATE TABLE StarFrame"+self.name+" (etc etc)")
这工作,但我想做更多的事情:
cursor.execute("CREATE TABLE StarFrame(?) (etc etc)",self.name)
虽然我明白这可能是不可能的。 尽pipe我会解决类似的问题
cursor.execute("CREATE TABLE (?) (etc etc)",self.name)
如果这不可能,我会接受这个答案,但如果有人知道这样做的方法,请告诉。 🙂
我在Python编码。
不幸的是,表格不能成为参数replace的目标(我没有find任何明确的来源,但我已经看到了几个networking论坛)。
如果你担心注入(你可能应该是),你可以编写一个函数,在传递之前清理string。 既然你正在寻找一个表名,你应该是安全的,只是接受字母数字,删除所有的标点符号,如)(][;,
和空格,基本上只是保持AZ az 0-9
。
def scrub(table_name): return ''.join( chr for chr in table_name if chr.isalnum() ) scrub('); drop tables --') # returns 'droptables'
我不会将数据分成多个表。 如果您在星号列上创build索引,则不会有任何问题有效地访问数据。
正如在其他答案中所说的,“表不能作为参数replace的目标”,但是如果你发现自己在一个没有select的绑定中,这里是一个testing提供的表名是否有效的方法。
注:我已经把表名称为一只真正的猪,试图涵盖所有的基地。
import sys import sqlite3 def delim(s): delims="\"'`" use_delim = [] for d in delims: if d not in s: use_delim.append(d) return use_delim db_name = "some.db" db = sqlite3.connect(db_name) mycursor = db.cursor() table = 'so""m ][ `etable' delimiters = delim(table) if len(delimiters) < 1: print "The name of the database will not allow this!" sys.exit() use_delimiter = delimiters[0] print "Using delimiter ", use_delimiter mycursor.execute('SELECT name FROM sqlite_master where (name = ?)', [table]) row = mycursor.fetchall() valid_table = False if row: print (table,"table name verified") valid_table = True else: print (table,"Table name not in database", db_name) if valid_table: try: mycursor.execute('insert into ' +use_delimiter+ table +use_delimiter+ ' (my_data,my_column_name) values (?,?) ',(1,"Name")); db.commit() except Exception as e: print "Error:", str(e) try: mycursor.execute('UPDATE ' +use_delimiter+ table +use_delimiter+ ' set my_column_name = ? where my_data = ?', ["ReNamed",1]) db.commit() except Exception as e: print "Error:", str(e) db.close()
您可以传递一个string作为SQL命令:
import sqlite3 conn = sqlite3.connect('db.db') c = conn.cursor() tablename, field_data = 'some_table','some_data' query = 'SELECT * FROM '+tablename+' WHERE column1=\"'+field_data+"\"" c.execute(query)