Recordemos de la clase anterior que para poder ejecutar consultas SQL debíamos realizar la conexión con la base de datos, para lo cual utilizabamos el paquete psycopg2
. También, recordemos que el código que empleabamos era algo largo, por ello, es conveniente crear una función para disminuir líneas de código, pero antes
# Primero importamos los paquetes que utilizaremos
import psycopg2
import pandas as pd
Ahora bien, bastará con copiar y pegar el código para la conexión y las consultas de la clase pasada dentro de una función que denominaremos execute_query
la cual recibirá como parámetro la consulta que deseamos realizar:
def execute_query(query_consul):
try:
# Creamos la conexion
conexion = psycopg2.connect(
user='postgres',
password='31416',
host='127.0.0.1',
port='5432',
database='CursoPostgres')
# Creamos un administrador de contexto para la conexion
# con la base de datos
with conexion:
# Creamos otro administrador para el cursor
with conexion.cursor() as cursor:
# Aquí será donde utilizaremos el parámetro de la función
query = query_consul
cursor.execute(query)
registros = cursor.fetchall()
df = pd.DataFrame(registros)
print(df)
# Arrojamos un mensaje en caso de error
except Exception as e:
print(f'Ocurrio un error: {e}')
# Finalmente cerramos la conexion y el cursor
finally:
conexion.close()
Probamos nuestra función:
# Indagamos sobre uan fila
execute_query('SELECT * FROM curso_python WHERE id_curso = 1')
0 1 2 3 4 0 1 Luis Apáez 24 CDMX
# Indagamos sobre una columna
execute_query('SELECT id_curso FROM curso_python')
0 0 1 1 2 2 3
# Vemos cuántos registros tenemos en la tabla curso_python
execute_query('SELECT COUNT(id_curso) FROM curso_python')
0 0 3
# Otro ejemplo
execute_query('SELECT * FROM curso_python WHERE id_curso IN (1,2)')
0 1 2 3 4 0 1 Luis Apáez 24 CDMX 1 2 Pedri López 14 Guadalajara
Cabe resaltar que al escribir cursor.fetcall
estamos considerando que el resultado involucrará más de una fila. Si deseamos optimizar el código, cuando realicemos consultas que sabemos que sólo se nos regresará una fila, entonces ocuparemos cursor.fetchone
.
Para insertar registros dentro de nuestra tabla curso_python
ocuparemos prácticamente la misma función, pero, como ahora estamos modificando la BD debemos guardar los cambios hechos, para ello debemos agregar a nuestro código conexion.commit()
. No obstante, lo anterior sólo debería hacerse si no estuvieramos trabajando con administradores de contexto. La ventaja de los administradores de contexto es que realizan dichos cambios de manera automática, por lo que en nuestro caso no es necesario agregar conexion.commit()
. Además, para este caso
#.
#.
registros = cursor.fetchall()
df = pd.DataFrame(registros)
print(df)
#.
#.
esta parte del código de la función no es útil pues no estamos realizando consultas. Otro detalle que debemos considerar es que, al momento de realizar una inserción, escribiremos para algún campo una cadena de texto, por ejemplo
'INSERT INTO curso_python(nombre, apellido, edad, Ciudad) VALUES('Erick', 'García', 19, 'CDMX')'
sin embargo lo anterior causaría un error y en su lugar deberíamos de escribir
'INSERT INTO curso_python(nombre, apellido, edad, Ciudad) VALUES(\'Erick\', \'García\', 19, \'CDMX\')'
lo cual, si bien es correcto, no es tan conveniente. Podemos solucionar lo anterior si escribirmos
query = 'INSERT INTO curso_python(nombre, apellido, edad, Ciudad) VALUES(%s, %s, %s, %s)'
values = ('Erick', 'García', 19, 'CDMX')
cursor.execute(query, values)
con lo cual se sustituirán las entradas de la tupla values
en los valores a ingresar del INSERT
, donde, para ello nos valimos de %s
y para realizar la ejecución adecuada se escribió cursor.execute(query, values)
. De modo que nuestra función quedaría como
def execute_query_insert(query_insert, values_tupla):
try:
# Creamos la conexion
conexion = psycopg2.connect(
user='postgres',
password='31416',
host='127.0.0.1',
port='5432',
database='CursoPostgres')
# Creamos un administrador de contexto para la conexion
# con la base de datos
with conexion:
# Creamos otro administrador para el cursor
with conexion.cursor() as cursor:
# Aquí será donde utilizaremos los parámetros de la función
query = query_insert
values = values_tupla
cursor.execute(query, values)
# Mostramos un mensaje de que la inserción ha sido exitosa
print("Inserción exitosa")
# Arrojamos un mensaje en caso de error
except Exception as e:
print(f'Ocurrio un error: {e}')
# Finalmente cerramos la conexion y el cursor
finally:
conexion.close()
Probamos nuestra función:
execute_query_insert('INSERT INTO curso_python(nombre, apellido, edad, Ciudad) VALUES(%s,%s,%s,%s)',
('Carlos', 'López', 24, 'Guadalajara'))
Inserción exitosa
Veamos ahora de nuevo nuestra tabla
execute_query('SELECT * FROM curso_python')
0 1 2 3 4 0 1 Luis Apáez 24 CDMX 1 2 Pedri López 14 Guadalajara 2 3 Luis Apáez 24 Toluca 3 4 Fer Luna 19 CDMX 4 11 Erick García 19 CDMX 5 12 Carlos López 24 Guadalajara
Podemos realizar varias inserciones en la misma tabla:
cadena = 'INSERT INTO curso_python(nombre, apellido, edad, Ciudad) VALUES(%s,%s,%s,%s)'
execute_query_insert(cadena, ('Ney', 'López', 32, 'Tijuana'))
execute_query_insert(cadena, ('Naye', 'López', 21, 'CDMX'))
execute_query_insert(cadena, ('Alex', 'López', 20, 'Tula'))
execute_query_insert(cadena, ('Iván', 'López', 16, 'Los Mochis'))
Inserción exitosa Inserción exitosa Inserción exitosa Inserción exitosa
Veamos los cambios hechos
execute_query('SELECT * FROM curso_python')
0 1 2 3 4 0 1 Luis Apáez 24 CDMX 1 2 Pedri López 14 Guadalajara 2 3 Luis Apáez 24 Toluca 3 4 Fer Luna 19 CDMX 4 11 Erick García 19 CDMX 5 12 Carlos López 24 Guadalajara 6 13 Ney López 32 Tijuana 7 14 Naye López 21 CDMX 8 15 Alex López 20 Tula 9 16 Iván López 16 Los Mochis