Imposta il nome dell'applicazione
Se si prevede di eseguire molti processi, è necessario sapere da dove si connettono. PGBouncer lo renderà invisibile a pg_stat_activity
. Risolvilo impostando application_name
con cura le informazioni necessarie:
# 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)
Preferisci sessioni
Utilizzare le sessioni poiché le richieste da un oggetto Engine possono essere generate e trattenute su più connessioni. La connessione a Postgres non è molto costosa, con PGBouncer lo è ancora di meno. Userei sempre in NullPool
modo che le uniche connessioni che vedrai in Postgres siano le connessioni effettivamente utilizzate.
from sqlalchemy.pool import Pool, NullPool
engine = create_engine(uri, poolclass=NullPool)
Elimina le transazioni inattive
Se il tuo intento è utilizzare PGBouncer per ridimensionare, è indispensabile evitare di lasciare aperte le transazioni. Per fare questo è necessario attivare autocommit
su . Questo non è semplice con SQLAlchemy ... ci sono tre posti in cui è possibile impostare qualcosa chiamato "autocommit":
psycopg2 autocommit
conn = psycopg2.connect(uri)
conn.autocommit = True
Si presume che non sia sicuro, poiché SQLAlchemy deve sapere cosa sta accadendo sotto.
Sessione autocommit
Session = sessionmaker(bind=engine, autocommit=True)
session = Session()
Ciò richiede una consegna attenta ed esplicita:
session.begin()
session.execute(...)
session.rollback()
La chiamata di funzione e la gestione delle eccezioni sono estremamente difficili perché
begin()
e commit()
non possono essere nidificate:
def A():
session.begin()
...
session.rollback()
def B():
session.begin()
try:
A() # error, already open
In questa modalità psycopg2 autocommit
sembra essere False
(impostazione predefinita)
Autocommit motore
L'impostazione della modalità di isolamento del motore su "AUTOCOMMIT"
quando si crea il motore stabilisce un nuovo comportamento predefinito che potrebbe non richiedere modifiche al codice esistente.
engine = create_engine(uri, isolation_level="AUTOCOMMIT")
In questa modalità autocommit
sembra essere psycopg2True
Il problema principale qui è che l'unico modo per garantire che un blocco di codice sia racchiuso in una transazione è di emettere le istruzioni manualmente:
session.execute("BEGIN")
#...
session.execute("COMMIT")