<jupyter_start><jupyter_text>Capítulo 4 - Uso de JayDeBeApi para consultar Bases de Datos___ Conexión___Para conectar con una base de datos se puede usar la librería `JayDeBeApi`:<jupyter_code>! pip install JayDeBeApi<jupyter_output><empty_output><jupyter_text>También hay que asegurarse de que la variable de entorno JAVA_HOME tiene la carpeta donde se ha instalado un jdk de Java1. Descargar e instalar Java jdk 1.8: https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html > "Java SE Development Kit" > {sistema operativo. Ej.: Windows} > "x64 installer"2. Añadir la variable de entorno JAVA_HOME = `C:\Program Files\Java\jdk{version}` (se sustituye `{version}` por la versión instalada. Ej.: `1.8.0_281`) Importamos el módulo y creamos la siguiente clase que nos facilita hacer querys a la BBDD:<jupyter_code>import jaydebeapi

class Database(object):

    def __init__(self, java_class_name, url, driver_args, jars):
        self.jaydebeapi_args = [java_class_name, url, driver_args, jars]

    def query(self, sql):
        with jaydebeapi.connect(*self.jaydebeapi_args) as connection:
            with connection.cursor() as cursor:
                cursor.execute(sql)
                if cursor.description:
                    headers = [x[0] for x in cursor.description]
                    rows = cursor.fetchall()
                    return [dict(zip(headers, row)) for row in rows]<jupyter_output><empty_output><jupyter_text>Creamos una base de datos [SQLite3](https://es.wikipedia.org/wiki/SQLite). A diferencia de las bases de datos tipo servidor, este tipo de BBDD guarda todo el contenido en un archivo. La cadena de conexión JDBC es `jdbc:sqlite:{path}` donde "path" es la ruta donde se creará dicho archivo (si no existe todavía)<jupyter_code>db = Database("org.sqlite.JDBC", "jdbc:sqlite:MySQLite.db", ["", ""], "sqlite-jdbc-3.36.0.3.jar")  # MySQLite.db es la ruta donde se creará la BBDD

db.query("select 1")<jupyter_output><empty_output><jupyter_text>Operaciones___ Create table<jupyter_code>db.query("""\
    CREATE TABLE IF NOT EXISTS tabla1 (
        contact_id INTEGER PRIMARY KEY,
        first_name TEXT    NOT NULL,
        last_name  TEXT,
        phone      TEXT    NOT NULL CHECK (length(phone) >= 9)
        );
    """)<jupyter_output><empty_output><jupyter_text>Insert<jupyter_code>db.query("""\
    INSERT INTO tabla1 (first_name, last_name, phone) VALUES('Alejandro', 'Manzanero', '987654321');
    """)

db.query("""\
    INSERT INTO tabla1 (first_name, last_name, phone)
    VALUES('Elon', 'Musk', '987654321');
    """)<jupyter_output><empty_output><jupyter_text>SelectCuando la query es de tipo "select" la respuesta de `db.query` será una lista de diccionarios, donde las keys equivalen a las columnas de la tabla. En cualquier otro caso la respuesta es `None`<jupyter_code>filas = db.query("select * from tabla1")

print('1:', filas)
print('2:', filas[0])
print('3:', filas[0]['first_name'])<jupyter_output><empty_output><jupyter_text>Update<jupyter_code>sql = """\
    UPDATE tabla1 SET first_name = 'Alex'
    where first_name = 'Alejandro';
    """

assert 'WHERE' in sql.upper()

db.query(sql)

rows = db.query("select * from tabla1")
for row in rows:
    print( row )<jupyter_output><empty_output><jupyter_text>Delete<jupyter_code>sql = """\
    DELETE FROM tabla1
    WHERE first_name = 'Elon';
    """

assert 'WHERE' in sql.upper()

db.query(sql)

rows = db.query("select * from tabla1")
for row in rows:
    print( row['first_name'] )<jupyter_output><empty_output><jupyter_text>Drop Table<jupyter_code>db.query("DROP TABLE tabla1")

print("deleted tabla1")

try:
    db.query("DROP TABLE tabla1")
except Exception:
    print("tabla1 doesn't exist")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11894624800425758, 'fraction_numerical': 0.017296434273549762, 'mean_word_length': 4.272089761570827, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 41, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '364987', 'license': 'MIT', 'n_tokens_mistral': 1389, 'n_tokens_neox': 1319, 'n_words': 348, 'path': 'test-lab/04 - data_bases.ipynb', 'repo_name': 'manzanero/curso-python-auto', 'size': '3758'}