Встановіть назву програми
Якщо ви очікуєте запуску багатьох процесів, вам потрібно знати, звідки вони з'єднуються. PGBouncer зробить це невидимим для pg_stat_activity
. Вирішіть це, обережно встановивши application_name
потрібну інформацію:
# 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)
Віддавайте перевагу сесіям
Використовуйте сеанси, оскільки запити від об'єкта Engine можуть нереститися та утримувати декілька з'єднань. Підключення до Postgres не дуже дороге, з PGBouncer це ще менше. Я завжди використовував би NullPool
так, що єдині з'єднання, які ви побачите в Postgres, - це з'єднання, які фактично використовуються.
from sqlalchemy.pool import Pool, NullPool
engine = create_engine(uri, poolclass=NullPool)
Усуньте непрацюючі транзакції
Якщо ваш намір полягає в тому, щоб використовувати PGBouncer для масштабування, необхідно обов'язково уникати транзакцій, які залишаються відкритими. Для цього вам необхідно звернутися autocommit
в . З SQLAlchemy це не просто ... Є три місця, де можна встановити щось, що називається "автокомісія":
psycopg2 автокомісія
conn = psycopg2.connect(uri)
conn.autocommit = True
Вважається небезпечним, оскільки SQLAlchemy повинен знати, що відбувається внизу.
Сеанс автокомісії
Session = sessionmaker(bind=engine, autocommit=True)
session = Session()
Це вимагає обережного, чіткого вручення:
session.begin()
session.execute(...)
session.rollback()
Функція виклику і виключення вручаючи надзвичайно важко , тому що
begin()
і commit()
не може бути вкладеним:
def A():
session.begin()
...
session.rollback()
def B():
session.begin()
try:
A() # error, already open
У цьому режимі, як autocommit
видається, є psycopg2 False
(за замовчуванням)
Автокомісія двигуна
Встановлення режиму ізоляції двигуна "AUTOCOMMIT"
при створенні двигуна встановлює нову поведінку за замовчуванням, яка може не вимагати змін до існуючого коду.
engine = create_engine(uri, isolation_level="AUTOCOMMIT")
У такому режимі, схоже, autocommit
є psycopg2True
Найголовніша проблема тут полягає в тому, що єдиний спосіб гарантувати, що блок коду вкладено в транзакцію, - це випромінювати оператори вручну:
session.execute("BEGIN")
#...
session.execute("COMMIT")