1ª Demo
📓 DemoBase: Servidor Quack y conexión remota desde Jupyter¶
🔍 ¿Qué muestra esta demostración?
Demostración completa y funcional para un cuaderno de Jupyter que muestra el nuevo modo servidor de DuckDB 2.0 mediante el protocolo Quack y la sentencia CONNECT. La demo está pensada para ejecutarse celda a celda y utiliza dos conexiones independientes para simular el servidor y el cliente dentro del mismo cuaderno.
CALL quack_serve(...): Convierte cualquier instancia de DuckDB en un servidor accesible por red.ATTACH ... (TOKEN ...): Establece la conexión segura al servidor Quack.CONNECT <alias>: Redirige la sesión SQL completa al servidor remoto, de modo que las consultas posteriores se ejecutan allí y los resultados se transmiten de vuelta.DISCONNECT: Devuelve la sesión a la base de datos local.
🛠️ Requisitos previos¶
Instalada la versión 2.0.0 (o superior) de DuckDB y el paquete jupyter:
pip install duckdb>=2.0.0
Celda 1: Importaciones y comprobación de versión¶
import duckdb
import threading
import time
import uuid
print(f"DuckDB versión: {duckdb.__version__}")
# Debe mostrar 2.0.0 o superior
Celda 2: Configuración del servidor Quack en un hilo separado¶
Para que el servidor no bloquee el cuaderno, lo lanzamos en un hilo en segundo plano. El servidor escuchará en localhost y usará un token de autenticación.
# Token de autenticación para el servidor
TOKEN = "duckdb_demo_token"
# Puerto por defecto de Quack
PORT = 9494
def run_quack_server():
"""Iniciar servidor Quack en un proceso/hilo independiente."""
# Crear conexión dedicada para el servidor (en memoria)
server_con = duckdb.connect()
# La extensión quack se autoinstala y autocaraga en el primer uso
server_con.execute(f"CALL quack_serve('quack:localhost:{PORT}', token = '{TOKEN}')")
# Mantener el servidor vivo hasta que el programa termine
# (En un cuaderno, el hilo se cerrará al reiniciar el kernel)
while True:
time.sleep(1)
# Lanzar servidor en modo demonio para que no bloquee
server_thread = threading.Thread(target=run_quack_server, daemon=True)
server_thread.start()
print(f"Servidor Quack iniciado en quack:localhost:{PORT} con token '{TOKEN}'")
# Un segundo para que el servidor se inicialice
time.sleep(1)
Celda 3: Conexión del cliente al servidor Quack¶
Ahora, desde una conexión cliente independiente, nos conectamos al servidor usando la sentencia ATTACH (con el token) y luego CONNECT para redirigir la sesión.
# Crear conexión cliente independiente
client_con = duckdb.connect()
# 1. Asociar servidor remoto usando el protocolo quack y el token
client_con.execute(f"""
ATTACH 'quack:localhost:{PORT}' AS remote_qk (TOKEN '{TOKEN}');
""")
# 2. Redirigir sesión actual al servidor remoto
client_con.execute("CONNECT remote_qk;")
print("Cliente conectado al servidor Quack remoto.")
Celdas 4 y 5: Creación de datos en el servidor y consulta remota¶
Una vez conectados, cualquier sentencia SQL que ejecutemos se enviará al servidor y los resultados se transmitirán de vuelta.
Crear tabla e insertar datos (la ejecución ocurre en el servidor)¶
client_con.execute("""
CREATE TABLE IF NOT EXISTS eventos (
id INTEGER,
nombre VARCHAR,
valor DOUBLE
);
INSERT INTO eventos VALUES
(1, 'clic', 10.5),
(2, 'vista', 20.0),
(3, 'clic', 7.2);
""")
Consultar datos remotos¶
resultado = client_con.execute("""
SELECT nombre, SUM(valor) AS total
FROM eventos
GROUP BY nombre
ORDER BY total DESC;
""").fetchall()
print("Resultados obtenidos desde el servidor:")
for fila in resultado:
print(f" {fila[0]}: {fila[1]}")
Celda 6: Desconexión y limpieza¶
Finalmente, nos desconectamos del servidor remoto y cerramos las conexiones.
# Desconectar
client_con.execute("DISCONNECT;")
print("Sesión desconectada del servidor remoto.")
# Cerramos las conexiones (el hilo del servidor se detendrá al reiniciar el kernel)
client_con.close()
# Nota: El servidor sigue escuchando en segundo plano hasta que se reinicie el kernel.
Conexión PostgreSQL/MySQL
Este ejemplo se puede modificar fácilmente para mostrar la conexión a PostgreSQL o MySQL usando CONNECT 'postgres://...', gracias al nuevo optimizador de pushdown remoto que envía las consultas al servidor en lugar de descargar las tablas completas.