Legen Sie den Anwendungsnamen fest
Wenn Sie davon ausgehen, dass viele Prozesse ausgeführt werden, müssen Sie wissen, von wo aus sie eine Verbindung herstellen. PGBouncer wird dies unsichtbar machen pg_stat_activity
. Lösen Sie dieses Problem, indem application_name
Sie die folgenden Informationen sorgfältig festlegen:
# 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)
Sitzungen bevorzugen
Verwenden Sie Sitzungen, da Anforderungen von einem Engine-Objekt mehrere Verbindungen erzeugen und beibehalten können. Das Herstellen einer Verbindung zu Postgres ist nicht sehr teuer, mit PGBouncer sogar noch weniger. Ich würde immer NullPool
so verwenden, dass die einzigen Verbindungen, die Sie in Postgres sehen, die Verbindungen sind, die tatsächlich verwendet werden.
from sqlalchemy.pool import Pool, NullPool
engine = create_engine(uri, poolclass=NullPool)
Beseitigen Sie inaktive Transaktionen
Wenn Sie PGBouncer zum Skalieren verwenden möchten, müssen Sie unbedingt vermeiden, dass Transaktionen offen bleiben. Um dies zu tun müssen Sie drehen autocommit
auf . Dies ist mit SQLAlchemy nicht einfach. Es gibt drei Stellen, an denen ein sogenanntes "Autocommit" festgelegt werden kann:
psycopg2 autocommit
conn = psycopg2.connect(uri)
conn.autocommit = True
Wird als unsicher eingestuft, da SQLAlchemy wissen muss, was darunter vor sich geht.
Session Autocommit
Session = sessionmaker(bind=engine, autocommit=True)
session = Session()
Dies erfordert eine sorgfältige, explizite Übergabe:
session.begin()
session.execute(...)
session.rollback()
Funktionsaufruf und Ausnahmegabe ist außerordentlich schwierig , da
begin()
und commit()
kann nicht verschachtelte:
def A():
session.begin()
...
session.rollback()
def B():
session.begin()
try:
A() # error, already open
In diesem Modus autocommit
scheint psycopg2 zu sein False
(Standardeinstellung)
Motor-Autocommit
Durch das Festlegen des Engine-Isolationsmodus "AUTOCOMMIT"
beim Erstellen der Engine wird ein neues Standardverhalten festgelegt, das möglicherweise keine Änderungen an vorhandenem Code erfordert.
engine = create_engine(uri, isolation_level="AUTOCOMMIT")
In diesem Modus autocommit
scheint psycopg2 zu seinTrue
Das Hauptproblem hierbei ist, dass die einzige Möglichkeit, sicherzustellen, dass ein Codeblock in eine Transaktion eingeschlossen wird, darin besteht, die Anweisungen manuell zu senden:
session.execute("BEGIN")
#...
session.execute("COMMIT")