Consultas parametrizadas
Prevenga la inyección SQL
Consultas parametrizadas es una lección gratuita de Python Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Python Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Python Academy incluye 4 lecciones en total.
El peligro de construir cadenas
Construir SQL concatenando cadenas es arriesgado. Si la entrada del usuario contiene SQL, puede cambiar su consulta. Esto se denomina inyección SQL.
No haga esto nunca con datos que no sean de confianza.
name = 'Alice'
# Unsafe pattern - do NOT do this
query = "SELECT * FROM users WHERE name = '" + name + "'"
print(query)Cómo es un intento de inyección
Imagine un valor malicioso. Al concatenarlo, el significado de la consulta cambia por completo.
name = "x' OR '1'='1"
query = "SELECT * FROM users WHERE name = '" + name + "'"
print(query)
print('The OR clause makes every row match!')Los marcadores de posición al rescate
La forma segura son las consultas parametrizadas. Use ? como marcador de posición y pase los valores como una tupla. El controlador los escapa de forma segura.
import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
cur.execute('INSERT INTO users (name) VALUES (?)', ('Alice',))
cur.execute('SELECT * FROM users')
print(cur.fetchall())
conn.close()Varios marcadores de posición
Use un ? por cada valor. Páselos en una tupla, en el mismo orden en que aparecen.
import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)')
cur.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('Bob', 25))
cur.execute('SELECT * FROM users')
print(cur.fetchall())
conn.close()Tuplas de un solo valor
Una tupla de un solo elemento necesita una coma final: ('Alice',). Sin ella, Python interpreta los paréntesis simplemente como agrupación.
good = ('Alice',)
bad = ('Alice')
print(type(good), type(bad))Intento de inyección bloqueado
Con los marcadores de posición, un valor malicioso se trata como datos simples, no como SQL. Simplemente no coincide con nada.
import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
cur.execute('INSERT INTO users (name) VALUES (?)', ('Alice',))
evil = "x' OR '1'='1"
cur.execute('SELECT * FROM users WHERE name = ?', (evil,))
print('Rows matched:', cur.fetchall())
conn.close()Marcadores de posición con nombre
SQLite también admite marcadores de posición con nombre mediante la sintaxis :name. Pase un diccionario de valores.
import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)')
cur.execute('INSERT INTO users (name, age) VALUES (:n, :a)', {'n': 'Carol', 'a': 40})
cur.execute('SELECT * FROM users')
print(cur.fetchall())
conn.close()Parámetros en WHERE
Los marcadores de posición funcionan en cualquier cláusula que acepte un valor, incluida WHERE.
import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)')
cur.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('Alice', 30))
cur.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('Bob', 25))
cur.execute('SELECT name FROM users WHERE age > ?', (28,))
print(cur.fetchall())
conn.close()executemany
Para insertar muchas filas, use executemany() con una lista de tuplas. Es más rápido y sigue siendo seguro.
import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
rows = [('Alice',), ('Bob',), ('Carol',)]
cur.executemany('INSERT INTO users (name) VALUES (?)', rows)
cur.execute('SELECT COUNT(*) FROM users')
print(cur.fetchone())
conn.close()Los marcadores de posición no sirven para identificadores
Los marcadores de posición solo funcionan con valores, no con nombres de tablas o columnas. Estos deben proceder de una lista blanca de confianza definida en su propio código.
import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
allowed = {'name', 'id'}
col = 'name'
if col in allowed:
cur.execute('SELECT ' + col + ' FROM users')
print('Safe column query ran')
conn.close()Una función de inserción reutilizable
Envolver las inserciones parametrizadas en una función mantiene el código limpio y seguro de forma coherente.
import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
def add_user(cursor, name):
cursor.execute('INSERT INTO users (name) VALUES (?)', (name,))
add_user(cur, 'Dave')
cur.execute('SELECT * FROM users')
print(cur.fetchall())
conn.close()Comprobación rápida
Compruebe sus conocimientos sobre las consultas seguras.
Resumen
Ha aprendido a escribir consultas seguras frente a la inyección.
- No concatene nunca entradas que no sean de confianza en SQL
- Use marcadores de posición
?con una tupla de valores - Los marcadores de posición con nombre
:namereciben un diccionario executemany()inserta muchas filas de forma segura- Los marcadores de posición son para valores, no para identificadores
Preguntas frecuentes
¿La lección «Consultas parametrizadas» es gratis?
Sí — el texto completo de «Consultas parametrizadas» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Python Academy, actualiza a CoddyKit PRO. El curso de Python Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Consultas parametrizadas»?
Prevenga la inyección SQL Practicas Python Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Python Academy?
No se requiere experiencia previa. Python Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.
¿Cuánto tiempo toma la lección «Consultas parametrizadas»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Python Academy?
Sí. Cada lección de Python Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Conexión y creación de tablas
- Insertar, seleccionar, actualizar y eliminar
- Consultas parametrizadas
- Transacciones y gestores de contexto