<jupyter_start><jupyter_text>Bases de datosLas bases de datos nos pueden servir como fuente, como destino de los resultados, o ambas. Vamos a ver cómo leer y escribir datos desde Python.Para estos ejemplos, utilizaremos una base de datos `sqlite` en local.<jupyter_code>import sqlite3
import pandas as pd<jupyter_output><empty_output><jupyter_text>ConexiónEsto varía dependiendo de la BD a la que te vayas a conectar:* sqlite: es neceario el módulo `sqlite3`, que vamos a utilizar* PostgreSQL: necesitas el módulo `psycopg2`* MySQL: hay varias alternativas, como `pymysql` o `mysqlclient`<jupyter_code>conn = sqlite3.connect('11_bd_temporal.sqlite')<jupyter_output><empty_output><jupyter_text>EscrituraPodemos volcar un dataframe a una tabla de la base de datos con [`DataFrame.to_sql`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_sql.html).<jupyter_code>alquiler = pd.read_csv('dat/alquiler-madrid-distritos.csv')
alquiler.head()
alquiler.to_sql('alquiler', conn)<jupyter_output><empty_output><jupyter_text>ConsultasPara lanzar consultas a la base de datos y obtener el resultado en un dataframe, podemos usar [`pd.read_sql()`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_sql.html)<jupyter_code>query = '''
select distrito, ano, quarter, precio
from alquiler
where distrito = 'Retiro'
and ano between 2012 and 2014
'''

pd.read_sql(query, conn)<jupyter_output><empty_output><jupyter_text>Parametrizar es importante para evitar inyección de SQL. Esto es especialmente importante si los datos son introducidos por usuarios. [xkcd](http://imgs.xkcd.com/comics/exploits_of_a_mom.png)  Carga de resultadosAunque hemos visto que se puede crear y alimentar una tabla en el momento con `to_sql`, lo más habitual es que nuestra base de datos ya tenga las tablas creadas (con su esquema bien definido, índices, claves foráneas, ...) y que queramos añadir datos.Vamos a crear una tabla definiendo su esquema, para ver como podríamos añadir los datos de un dataframe sin crearla de cero en `to_sql`.<jupyter_code>c = conn.cursor()
c.execute('''create table alquiler_2
             (distrito text, ano integer, quarter integer, precio real)''')<jupyter_output><empty_output><jupyter_text>Comprobamos que está vacía<jupyter_code>pd.read_sql('select * from alquiler_2', conn)<jupyter_output><empty_output><jupyter_text>Agregamos los datos a la tabla existente<jupyter_code>alquiler.to_sql('alquiler_2', conn, index=False, if_exists='append')
pd.read_sql('select * from alquiler_2 limit 5', conn)<jupyter_output><empty_output><jupyter_text>Cierre de conexión<jupyter_code>conn.close()<jupyter_output><empty_output>
StarcoderdataJupyterStructuredCleanDedup