我正在运行 PostgreSQL 9.6(在 Docker 中,使用 postgres:9.6.13 图像)和 psycopg2 2.8.2。
我的 PostgreSQL 服务器(本地)托管两个数据库。我的目标是使用 Postgres 的外部数据包装器在一个使用来自另一个数据库的数据的数据库中创建物化 View 。我通过使用 psycopg2 的 Python 脚本执行所有这些操作。
只要创建物化 View 不会花费太长时间(即,如果导入的数据量不是太大),这就很有效。但是,如果该过程花费的时间超过大约 250 秒,psycopg2 将抛出异常
psycopg2.OperationalError: server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
在 Postgres 的日志中找不到错误消息(或任何与此相关的消息)。
如果我从 SQL 客户端 (Postico) 创建物化 View ,它会成功完成。
这段代码大致说明了我在 Python 脚本中所做的事情:
db = pg.connect(
dbname=config.db_name,
user=config.db_user,
password=config.db_password,
host=config.db_host,
port=config.db_port
)
with db.cursor() as c:
c.execute("""
CREATE EXTENSION IF NOT EXISTS postgres_fdw;
CREATE SERVER fdw FOREIGN DATA WRAPPER postgres_fdw OPTIONS (...);
CREATE USER MAPPING FOR CURRENT_USER SERVER fdw OPTIONS (...);
CREATE SCHEMA foreign;
IMPORT FOREIGN SCHEMA foreign_schema FROM SERVER fdw INTO foreign;
""")
c.execute("""
CREATE MATERIALIZED VIEW IF NOT EXISTS my_view AS (
SELECT (...)
FROM foreign.foreign_table
);
""")
最佳答案
将keepalive
参数添加到psycopg2.connect
调用似乎已经解决了问题:
self.db = pg.connect(
dbname=config.db_name,
user=config.db_user,
password=config.db_password,
host=config.db_host,
port=config.db_port,
keepalives=1,
keepalives_idle=30,
keepalives_interval=10,
keepalives_count=5
)
我仍然不知道为什么这是必要的。我找不到任何其他人描述过在 Docker 中使用 Postgres 时必须使用 keepalives
参数关键字才能运行超过 4-5 分钟的查询,但也许这很明显没人注意到吗?
关于python - 使用 Psycopg2 时,Postgres 在查询期间在几百秒后关闭连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56557460/