Defina o nome do aplicativo
Se você espera executar muitos processos, precisa saber de onde eles estão se conectando. O PGBouncer tornará isso invisível para pg_stat_activity
. Resolva isso configurando cuidadosamente application_name
as informações necessárias:
# 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)
Preferir sessões
Use Sessões, pois as solicitações de um objeto Engine podem gerar e manter várias conexões. Conectar-se ao Postgres não é muito caro, com o PGBouncer é ainda menos. Eu sempre usaria NullPool
para que as únicas conexões que você verá no Postgres sejam as conexões que realmente estão sendo usadas.
from sqlalchemy.pool import Pool, NullPool
engine = create_engine(uri, poolclass=NullPool)
Eliminar transações inativas
Se sua intenção é usar o PGBouncer para escalar, é essencial que você evite deixar as transações em aberto. Para fazer isso você precisa se transformar autocommit
em . Isso não é simples com o SQLAlchemy ... há três lugares em que algo chamado "confirmação automática" pode ser definido:
confirmação automática de psycopg2
conn = psycopg2.connect(uri)
conn.autocommit = True
Presume-se inseguro, porque o SQLAlchemy precisa saber o que está acontecendo por baixo.
Confirmação automática de sessão
Session = sessionmaker(bind=engine, autocommit=True)
session = Session()
Isso requer uma entrega cuidadosa e explícita:
session.begin()
session.execute(...)
session.rollback()
Função de chamada e entregar exceção é extremamente difícil porque
begin()
e commit()
não pode ser aninhada:
def A():
session.begin()
...
session.rollback()
def B():
session.begin()
try:
A() # error, already open
Nesse modo, o psycopg2 autocommit
parece ser False
(o padrão)
Confirmação automática do motor
Definir o modo de isolamento do mecanismo como "AUTOCOMMIT"
ao criar o mecanismo estabelece um novo comportamento padrão que pode não exigir alterações no código existente.
engine = create_engine(uri, isolation_level="AUTOCOMMIT")
Nesse modo, o psycopg2 autocommit
parece estarTrue
O principal problema aqui é que a única maneira de garantir que um bloco de código seja envolvido em uma transação é emitir as instruções manualmente:
session.execute("BEGIN")
#...
session.execute("COMMIT")