Définissez le nom de l'application
Si vous prévoyez d'exécuter de nombreux processus, vous devez savoir d'où ils se connectent. PGBouncer rendra cela invisible pg_stat_activity
. Résolvez cela en définissant soigneusement le application_name
avec les informations dont vous aurez besoin:
# 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)
Préférer les sessions
Utilisez Sessions, car les demandes d'un objet Engine peuvent apparaître et s'accrocher à plusieurs connexions. Se connecter à Postgres n'est pas très cher, avec PGBouncer c'est encore moins le cas. J'utiliserais toujours NullPool
pour que les seules connexions que vous verrez dans Postgres soient les connexions qui sont réellement utilisées.
from sqlalchemy.pool import Pool, NullPool
engine = create_engine(uri, poolclass=NullPool)
Éliminer les transactions inactives
Si votre intention est d'utiliser PGBouncer pour évoluer, il est impératif d'éviter de laisser les transactions bloquées. Pour ce faire , vous devez activer autocommit
le . Ce n'est pas simple avec SQLAlchemy ... il y a trois endroits où quelque chose appelé "autocommit" peut être défini:
autocommit psycopg2
conn = psycopg2.connect(uri)
conn.autocommit = True
Présumé dangereux dangereux car SQLAlchemy doit savoir ce qui se passe en dessous.
Autocommit de session
Session = sessionmaker(bind=engine, autocommit=True)
session = Session()
Cela nécessite une remise soigneuse et explicite:
session.begin()
session.execute(...)
session.rollback()
L'appel de fonction et la remise d'exception sont extrêmement difficiles car
begin()
et commit()
ne peuvent pas être imbriqués:
def A():
session.begin()
...
session.rollback()
def B():
session.begin()
try:
A() # error, already open
Dans ce mode, psycopg2 autocommit
semble être False
(par défaut)
Autocommit du moteur
La définition du mode d'isolation du moteur "AUTOCOMMIT"
lors de la création du moteur établit un nouveau comportement par défaut qui peut ne pas nécessiter de modifications du code existant.
engine = create_engine(uri, isolation_level="AUTOCOMMIT")
Dans ce mode, psycopg2 autocommit
semble êtreTrue
Le problème majeur ici est que la seule façon de garantir qu'un bloc de code est encapsulé dans une transaction est d'émettre les instructions manuellement:
session.execute("BEGIN")
#...
session.execute("COMMIT")