Requisitos previos
- uv y Python 3.11 o posterior. Esta guía se ha probado con Python 3.13, FastAPI 0.142, SQLAlchemy 2.1, asyncpg 0.31, Alembic 1.20 y Uvicorn 0.54.
- Una cuenta de ClickHouse Cloud
psql, para crear la base de datos. También puede ejecutar la sentenciaCREATE DATABASEen la consola SQL.
Crear un servicio de ClickHouse Managed Postgres
En la consola de ClickHouse Cloud, haga clic en New service y seleccione Postgres. La instancia estará lista en unos minutos. Para ver el proceso paso a paso, consulte la guía de inicio rápido.Obtenga los detalles de conexión
Haga clic en Conectar en la barra lateral izquierda de su servicio. El cuadro modal muestra su nombre de usuario, contraseña, servidor y puerto, e incluye un toggle Directly / via PgBouncer. Esta guía utiliza ambas conexiones:- PgBouncer (puerto
6432) para la aplicación. SQLAlchemy mantiene un grupo de conexiones en cada worker de Uvicorn, y el PgBouncer integrado permite que muchos workers y réplicas compartan un número reducido de conexiones de Postgres. Funciona en modo de agrupación por transacción (transaction pooling). - Directa (puerto
5432) para Alembic. Las migraciones ejecutan DDL, pueden prolongarse durante mucho tiempo y pueden depender del estado de la sesión, por lo que conviene que se comuniquen directamente con Postgres.
sslmode=verify-full&sslrootcert=.... asyncpg no lee estos parámetros, así que copie únicamente la contraseña y el host del cuadro modal. En su lugar, la aplicación pasa el certificado de la CA desde el código (consulte Configurar la conexión).
Configurar el proyecto
Cree un proyecto e instale FastAPI, Uvicorn, SQLAlchemy con el extraasyncio, asyncpg y Alembic:
Configurar la conexión
Mueva el certificado de CA que descargó al directorio del proyecto y cámbiele el nombre aca-certificate.pem.
Cree una base de datos para la aplicación. Sustituya <PASSWORD> y el host por los valores que aparecen en el cuadro de diálogo Conectar:
.env en la raíz del proyecto o agregue estas variables al que ya tenga. Las dos URL solo se diferencian en el puerto, utilizan el esquema postgresql+asyncpg y no incluyen parámetros de SSL:
.env
DATABASE_CA_CERT se resuelve en relación con el directorio desde el que ejecuta los comandos. Si su contraseña contiene caracteres especiales como @, / o #, aplíqueles codificación URL. No incluya .env en el control de versiones.
Cree app/db.py. Este archivo define la configuración de TLS, el motor y una fábrica de sesiones que comparte el resto de la aplicación:
app/db.py
ssl.SSLContext creado con PROTOCOL_TLS_CLIENT exige un certificado válido y comprueba el nombre del host, lo que equivale a sslmode=verify-full. SQLAlchemy lo pasa a asyncpg a través de connect_args.
Si prefiere mantener la configuración de TLS en la URL, o si su aplicación usa sesiones síncronas de SQLAlchemy, utilice el controlador psycopg en lugar de asyncpg. Está basado en libpq y acepta los parámetros del modal Conectar, por ejemplo
postgresql+psycopg://...:5432/guide_fastapi?sslmode=verify-full&sslrootcert=ca-certificate.pem, tanto con create_engine como con create_async_engine.Definir el modelo
Creeapp/models.py con un modelo tipado de SQLAlchemy:
app/models.py
Ejecutar migraciones
Cree un entorno de Alembic a partir de la plantilla async:migrations/env.py generado. La nueva versión carga sus modelos para que autogenerate pueda usarlos y se conecta directamente a Postgres con la misma configuración de TLS que la aplicación:
migrations/env.py
sqlalchemy.url de alembic.ini, ya que env.py crea el motor por su cuenta.
Genere una migración a partir del modelo y, a continuación, aplíquela:
migrations/versions y haga commit de este junto con su código. Alembic registra la revisión aplicada en la tabla alembic_version. Cada vez que modifique un modelo, vuelva a ejecutar revision --autogenerate y upgrade head.
Añadir los endpoints de la API
Creeapp/main.py. Cada solicitud obtiene su propia AsyncSession a través de una dependencia de FastAPI, y el grupo de conexiones del motor se cierra al apagarse la aplicación:
app/main.py
session.commit. Cuando se cierra la sesión, se revierte cualquier trabajo sin commit. Al hacer un INSERT, SQLAlchemy recupera los valores generados de id y created_at mediante RETURNING, por lo que create_todo no necesita una consulta adicional.
Ejecutar y verificar
Inicie la aplicación:DELETE devuelve 204 No Content. Si se solicita una tarea que no existe, se devuelve 404:
pg_stat_ssl con la misma configuración de TLS que usa la aplicación:
guide_fastapi y después public, y haga clic en la tabla todos. La tabla alembic_version, que aparece junto a ella, almacena el historial de migraciones. La tabla todos contiene la fila restante:
Detenga la aplicación con Ctrl+C.
Uso de PgBouncer
La aplicación funciona a través de PgBouncer con la configuración predeterminada de asyncpg y SQLAlchemy:- asyncpg ejecuta cada consulta como una sentencia preparada con nombre a nivel de protocolo, y SQLAlchemy almacena en caché hasta 100 de ellas por conexión. El PgBouncer incluido admite estas sentencias en el modo de agrupación por transacciones, y asyncpg las libera con un mensaje
Closea nivel de protocolo en lugar de con la sentencia SQLDEALLOCATE. No necesitastatement_cache_size=0ni unaprepared_statement_name_funcpersonalizada. Si aun así desactiva la caché de sentencias de asyncpg, añada tambiénprepared_statement_cache_size=0a la URL para desactivar la caché de SQLAlchemy. - La configuración de sesión establecida con
SET, comosearch_path, no se conserva en la siguiente transacción y puede filtrarse a otros clientes. En su lugar, utiliceSET LOCALdentro de una transacción. pg_stat_sslinforma sobre la conexión entre PgBouncer y Postgres, por lo que la comprobación de TLS anterior devuelve(False, None)a través del puerto6432. Aun así, la conexión de la aplicación con PgBouncer se sigue verificando: un certificado de CA incorrecto falla de la misma manera.- Alembic no adquiere bloqueos consultivos y ejecuta cada
upgradeen una sola transacción, por lo que también funciona a través de PgBouncer. Aun así, para migraciones largas es preferible usar la conexión directa.
Próximos pasos
- Conexión: cadenas de conexión, PgBouncer y TLS
- Configuración: parámetros de Postgres y PgBouncer, como
max_connections - Réplicas de lectura: envíe consultas de solo lectura a una réplica con un segundo motor
- Seguridad: listas de acceso por IP y redes privadas