Answers:
设置应用名称
如果您希望运行许多进程,则需要知道它们从何处连接。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
在此模式下,psycopg2 autocommit
似乎是False
(默认值)
引擎自动提交
"AUTOCOMMIT"
在创建引擎时将引擎隔离模式设置为可以建立新的默认行为,该行为可能不需要更改现有代码。
engine = create_engine(uri, isolation_level="AUTOCOMMIT")
在此模式下,psycopg2 autocommit
似乎是True
这里的主要问题是,保证代码块包装在事务中的唯一方法是手动发出语句:
session.execute("BEGIN")
#...
session.execute("COMMIT")