Continuamos con la serie de tutoriales sobre hacer CRUD con Python, específicamente el framework Bottle y la base de datos MySQL, pero esta vez nos centraremos en insertar los datos. En el tutorial anterior vimos como realizar una consultar y listar los resultados, el cuál haremos referencia. Así que no los has visto te dejo el link a continuación:

Previamente: Python MySQL: Consulta de datos usando Bottle

Seguiremos usando algunos archivos del tutorial anterior y añadiremos algunas funciones y modificaremos algún que otro código para que se adapte a nuestro requerimiento de hoy: insertar los datos. Aunque también veremos algunas funciones extras con las cuenta Bottle.

Aunque he intentando hacer el código lo más entendible posible. Igual comentaremos el propósito de algunas funciones. Empezemos!

Usaremos la misma tabla crud_employees (del tutorial previo).

Nuestro archivo principal

Nuestro archivo principal se llama webapp.py, es el siguiente y luego explicaremos los cambios:

from bottle import route, run, template, request, static_file, debug
import mysql.connector
cnx = mysql.connector.connect(user='root', password='',host='127.0.0.1',database='db_emocion')
@route('/list')
def list():
    global cnx
    cursor = cnx.cursor()
    query = ("SELECT * FROM crud_employees")
    cursor.execute(query)
    result = cursor.fetchall()
    cursor.close()
    return template('list_template', rows=result)
@route ('/new')
def new():
    return template('new_employee.tpl')
@route('/save', method='POST')
def save():
    global cnx
    names = request.POST.Names.strip()
    address = request.POST.Address.strip()
    date_register = request.POST.Date_register.strip()
    phone = request.POST.Phone.strip()
    comment = request.POST.Comment.strip()
    salary = request.POST.Salary.strip()
    cursor = cnx.cursor()
    cursor.execute( "INSERT INTO crud_employees (names, address, date_register, phone, comment, salary) VALUES (%s, %s, %s, %s, %s, %s)", (names, address, date_register, phone, comment, salary) )
    cnx.commit()
    cursor.close()
    return '<p>El nuevo empleado fue agregado a la base de datos</p><p><a href="/list">Regresar al listado</a></p>'
@route('/static/<filename>')
def server_static(filename):
    return static_file(filename, root='files/')
debug(True)
run(host='localhost', port=8080)

En la primera línea hemos importados dos elementos mas de Bottle: request, que permite manejar las peticiones tipo GET, POST, etc; y static_files, que permite agregar archivos estáticos a nuestro proyecto, como imágenes, hojas de estilos, etc. En este caso lo usaremos para añadir una hoja de estilo.

En el artículo anterior, dentro de la función list, definimos la variable cnx, que contiene la conexión a la base de datos. Pero en está ocasión sera una variables global e ira fuera del ámbito de la función, con el fin de que otras funciones puedan usarla.

Continuando, definimos la url /new, relacionada con la función new(), que no hace más que llamar a un template, en este caso new_employee.tpl, que contiene un formulario donde agregaremos los datos del nuevo empleado. Luego mostraremos el código de este.

Seguimos, ahora definimos la url /save, esto llama a la función save(), que -efectivamente- guardar los datos de capturados del formulario en la base de datos. Llamamos a la variable de conexión cnx, y asignamos a variables locales los datos capturamos del formulario. Ejecutamos la consulta mediante, cursor.execute( "INSERT.. y si todo sale bien, mostrará un mensaje de que los datos fueron agregados a base de datos.

Definimos otra ruta, en este caso será para los archivos estáticos. Podríamos pensar que referenciar archivos locales como imagenes, css, etc; sería fácil, como referenciarlo desde la cabecera HTML desde una ruta. Pero.. no es así. Como medida de seguridad los archivos que usaremos en nuestro proyecto también debemos definir una ruta personalizada para usarlos.

La ruta será @route('/static/<filename>') y esta relacionada con la función server_static(file_name) que llama al archivo que especifiquemos como parámetro de entrada, en el directorio establecido, en nuestro caso definimos el directorio files donde alojaremos los archivos estáticos.

Nuestro plantilla para nuevo empleado

Ahora explicaremos la plantilla new_employee.tpl que definimos en la función new(), veamos el código primero.

% include('header.tpl')
		<h2>MySQL + Python (Bottle)</h2>
    <p>Registra los datos del nuevo empleado</p>
    <form action="/save" method="POST">
			<label>Nombres:
				<input type="text" name="Names" />
			</label>
			<label>Dirección:
				<input type="text" name="Address" />
			</label>
			<label>Fecha registro
				<input type="date" name="Date_register" />
			</label>
			<label>Telefono
				<input type="tel" name="Phone" />
			</label>
			<label>Comentario
				<textarea name="Comment"></textarea>
			</label>
			<label>Salario
				<input type="number" step=".01" name="Salary" />
			</label>
			<button type="submit" value="Save">Enviar datos</button>
		</form>
		<p><a href="/list">Regresar a listado</a></p>
% include('footer.tpl')

Expliquemos: un detalle inicial es que hemos separados algunos fragmentos HTML para no repetirlo en cada página, como la cabecera y el pie de página, haciendo uso de % include, llamamos a otras partes o fragmentos de plantilla.

Por lo demás vemos que es un formulario sin nada excepcional. En el atributo action establecemos la url /save, que se encarga de capturar los datos de este formulario y los almacenará en la base de datos, mediante el método POST.

Antes de terminar

Previamente definimos una ruta para archivos estáticos, quiero mostrarte donde lo usamos: en el archivo header.tpl, para añadir una hoja de estilos: styles.css (que estará añadida en el paquete de descarga)

<!DOCTYPE html>
<html lang="es">
	<head>
    <meta charset="utf-8">
    <title>Python MySQL</title>
    <link rel="stylesheet" href="static/styles.css" />
  </head>
  <body>

Físicamente el directorio static/ no existe, pero lo definimos como una ruta para los archivos estáticos, y la función server_static(filename) se encargará de agregarlos desde el directorio /files. Todo esto le añade seguridad a nuestros proyectos web.

Ejecutamos nuestro proyecto desde la consola, vamos al directorio donde tenemos nuestro proyecto y escribimos:

pythons webapp.py

Y vamos a localhost:8080/list. Pulsamos en link para agregar nuevo empleado y seguimos el proceso.

En resumen:

Hemos visto como insertar datos mediante Bottle(Python) a MySQL, pero también hemos aprendido como capturar datos mediante el método post, get usando request; además como hacer uso de archivos estáticos locales mediante static_file; y finalmente como incluir plantillas dentro de otras. Puedes descargar los archivos:

En los siguientes artículos explicaremos como actualizar los datos del empleado.