with instalar fetchmany descargar python database sqlite

python - instalar - Nombre de la tabla de variables en sqlite



sqlite3 python install (6)

Pregunta: ¿Es posible usar una variable como el nombre de su tabla sin tener que usar constructores de cadenas para hacerlo?

Información:

Estoy trabajando en un proyecto en este momento que cataloga datos de una simulación de estrellas mía. Para hacerlo, estoy cargando todos los datos en una base de datos sqlite. Está funcionando bastante bien, pero he decidido agregar mucha más flexibilidad, eficiencia y facilidad de uso a mi db. Planeo luego agregar planetoides a la simulación, y quería tener una tabla para cada estrella. De esta forma no tendría que consultar una tabla de 20m de algunos planetoides para el 1-4k en cada sistema solar.

Me han dicho que el uso de constructores de cadenas es malo porque me deja vulnerable a un ataque de inyección SQL. Si bien eso no es un gran problema aquí ya que soy la única persona con acceso a estos db, me gustaría seguir las mejores prácticas. Y también de esta manera, si hago un proyecto con una situación similar en la que esté abierto al público, sé qué hacer.

Actualmente estoy haciendo esto:

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

Esto funciona, pero me gustaría hacer algo más como:

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

aunque entiendo que esto probablemente sea imposible. aunque me conformaría con algo así como

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

Si esto no es posible, aceptaré esa respuesta, pero si alguien sabe cómo hacerlo, dígaselo. :)

Estoy codificando en Python.


Como se ha dicho en las otras respuestas, "las tablas no pueden ser el objetivo de la sustitución de parámetros", pero si se encuentra en un enlace donde no tiene opción, aquí hay un método para probar si el nombre de tabla proporcionado es válido.
Nota: He convertido el nombre de la tabla en un verdadero cerdo en un intento de cubrir todas las bases.

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


Desafortunadamente, las tablas no pueden ser el objetivo de la sustitución de parámetros (no encontré ninguna fuente definitiva, pero la he visto en algunos foros web).

Si le preocupa la inyección (probablemente deba hacerlo), puede escribir una función que limpie la cuerda antes de pasarla. Ya que solo busca un nombre para la tabla, debería estar seguro al aceptar los caracteres alfanuméricos, eliminando todos los signos de puntuación, tales como )(][;, y el espacio en blanco. Básicamente, simplemente mantenga AZ az 0-9 .

def scrub(table_name): return ''''.join( chr for chr in table_name if chr.isalnum() ) scrub(''); drop tables --'') # returns ''droptables''


No separaría los datos en más de una tabla. Si crea un índice en la columna de la estrella, no tendrá problemas para acceder de manera eficiente a los datos.


Para las personas que buscan una manera de hacer que la tabla sea una variable, obtuve esto de otra respuesta a la misma pregunta here :

Dijo lo siguiente y funciona. Todo está citado de mhawke :

No puede usar la sustitución de parámetros para el nombre de la tabla. Necesita agregar el nombre de la tabla a la cadena de consulta usted mismo. Algo como esto:

query = ''SELECT * FROM {}''.format(table) c.execute(query)

Una cosa a tener en cuenta es la fuente del valor para el nombre de la tabla. Si proviene de una fuente no confiable, por ejemplo, un usuario, entonces debe validar el nombre de la tabla para evitar posibles ataques de inyección SQL. Una forma podría ser construir una consulta parametrizada que busque el nombre de la tabla desde el catálogo DB:

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


Pruebe con el formato de cadenas:

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

Reemplace ''table_name'' con su deseo.


Puede pasar una cadena como el comando 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)