Establecer el nombre de la aplicación
Si espera ejecutar muchos procesos, necesita saber desde dónde se conectan. PGBouncer lo hará invisible para pg_stat_activity
. Resuelva esto configurando cuidadosamente application_name
la información que necesitará:
# Sets the application name for this connection in the form of
# application-name:user@host
prog = os.path.basename(sys.argv[0]) or 'desjob'
username = pwd.getpwuid (os.getuid ()).pw_name
hostname = socket.gethostname().split(".")[0]·
args.setdefault('connect_args', {'application_name': "%s:%s@%s" %
(prog, username, hostname)})
args.setdefault('isolation_level', "AUTOCOMMIT")
engine = create_engine(url, **args)
Prefiero Sesiones
Use Sesiones ya que las solicitudes de un objeto Engine pueden generar y mantener múltiples conexiones. Conectarse a Postgres no es muy costoso, con PGBouncer lo es aún menos. Siempre usaría NullPool
para que las únicas conexiones que verá en Postgres sean las conexiones que realmente se están utilizando.
from sqlalchemy.pool import Pool, NullPool
engine = create_engine(uri, poolclass=NullPool)
Eliminar transacciones inactivas
Si su intención es usar PGBouncer para escalar, entonces es imprescindible que evite dejar las transacciones abiertas. Para ello es necesario activar autocommit
el . Esto no es simple con SQLAlchemy ... hay tres lugares donde se puede configurar algo llamado "autocommit":
psycopg2 autocommit
conn = psycopg2.connect(uri)
conn.autocommit = True
Se presume que no es seguro porque SQLAlchemy necesita saber qué sucede debajo.
Compromiso automático de sesión
Session = sessionmaker(bind=engine, autocommit=True)
session = Session()
Esto requiere una entrega cuidadosa y explícita:
session.begin()
session.execute(...)
session.rollback()
Llamando a la función y la entrega excepción es extremadamente difícil debido
begin()
y commit()
no pueden anidarse:
def A():
session.begin()
...
session.rollback()
def B():
session.begin()
try:
A() # error, already open
En este modo, autocommit
parece que psycopg2 es False
(el valor predeterminado)
Compromiso automático del motor
Establecer el modo de aislamiento del motor en "AUTOCOMMIT"
cuando se crea el motor establece un nuevo comportamiento predeterminado que puede no requerir cambios en el código existente.
engine = create_engine(uri, isolation_level="AUTOCOMMIT")
En este modo, psycopg2 autocommit
parece serTrue
El principal problema aquí es que la única forma de garantizar que un bloque de código se envuelva en una transacción es emitir las declaraciones manualmente:
session.execute("BEGIN")
#...
session.execute("COMMIT")