写入谷歌云 postgresql 数据库的连接网络错误

Posted

技术标签:

【中文标题】写入谷歌云 postgresql 数据库的连接网络错误【英文标题】:Connection network error writing to google cloud postgresql database 【发布时间】:2022-01-23 08:54:39 【问题描述】:

我是 Web 开发的新手。我的任务是从 web api 下载大量数据,并将它们上传到 google cloud 上的 postgres 数据库中。

因为数据量很大,所以我有一个for循环,逐部分刮取数据,将每一部分插入到云表中,最后commit一切。我使用 sqlalchemy 和 pg8000 来完成这项工作。

这是我的代码的基本结构:

engine = create_engine("postgresql+pg8000://connection/info")
session = scoped_session(sessionmaker(autocommit=False,autoflush=False,bind=engine))
Base = declarative_base()

class MyTableClass(Base):
    some columns

Base.metadata.create_all(engine)

for part in scraping_data():
    engine.execute(MyTableClass.__table__.insert(), part)

session.commit()
session.close()
engine.dispose()

for 循环成功运行了 12 小时。然后我收到一个网络错误。这是第一部分。错误信息的其余部分很长,只是第一部分引起的一串错误。

ERROR:sqlalchemy.pool.impl.QueuePool:Exception closing connection <pg8000.legacy.Connection object at 0x7fa2ba514160>
Traceback (most recent call last):
    File "/home/user/anaconda3/envs/myenv/lib/python3.8/site-packages/pg8000/core.py", line 760, in handle_messages
    code, data_len = ci_unpack(self._read(5))
    struct.error: unpack_from requires a buffer of at least 5 bytes for unpacking 5 bytes at offset 0 (actual buffer size is 0)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/user/anaconda3/envs/myenv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1782, in _execute_context
    self.dialect.do_executemany(
  File "/home/user/anaconda3/envs/myenv/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 716, in do_executemany
    cursor.executemany(statement, parameters)
  File "/home/user/anaconda3/envs/myenv/lib/python3.8/site-packages/pg8000/legacy.py", line 304, in executemany
    self.execute(operation, parameters)
  File "/home/user/anaconda3/envs/myenv/lib/python3.8/site-packages/pg8000/legacy.py", line 252, in execute
    self._context = self._c.execute_unnamed(
  File "/home/user/anaconda3/envs/myenv/lib/python3.8/site-packages/pg8000/core.py", line 649, in execute_unnamed
    self.handle_messages(context)
  File "/home/user/anaconda3/envs/myenv/lib/python3.8/site-packages/pg8000/core.py", line 762, in handle_messages
    raise InterfaceError("network error on read") from e
pg8000.exceptions.InterfaceError: network error on read

谁能帮我解释一下这个错误?

我的连接似乎刚刚超时。谁能帮我更好地构建代码以避免在超时发生时丢失大量下载数据?

谢谢!

【问题讨论】:

根据link,异常 pg8000.errors.InterfaceError(Error) 是针对与数据库接口而非数据库本身相关的错误引发的通用异常。例如,如果接口尝试使用 SSL 连接但服务器拒绝,则会引发 InterfaceError。检查您是否在项目中启用了 Service Networking API。如果您尝试将私有 IP 地址分配给 Cloud SQL 实例,并且您使用的是共享 VPC,则还需要为宿主项目启用服务网络 API。 CSV 和 SQL 格式的导出方式不同。 SQL 格式包括整个数据库,可能需要更长时间才能完成。使用 CSV 格式并运行多个较小的导出作业,以减少每个操作的大小和长度,以避免导出期间超时。也许 temp_file_limit 标志设置得太低,不适合您的数据库使用。增加 temp_file_limit 大小。 (cloud.google.com/sql/docs/postgres/…) 检查您是否正确地确定了 sqlalchemy 会话的范围,如下所述:flask.palletsprojects.com/en/1.1.x/patterns/sqlalchemy 具体来说,当使用 scoped_session 时,您不会使用 @app.teardown_context 装饰器删除会话。请关注此documentation 以查看您的案例是否满足所有连接问题清单。 嗨,eddie,你能解决这个问题吗?如果我的 cmets 有帮助并且确实有助于解决您的问题。我可以将其发布为答案吗? @PriyashreeBhadra 是的。最后,我将我的出口工作分解为更小的工作。您指出的其他潜在问题似乎没有引起任何问题。 【参考方案1】:

正如@Eddie 所证实的那样,他的问题已通过将他的出口工作分解为较小的工作来解决。我将发布 cmets(故障排除步骤/潜在问题)作为任何遇到相同问题的人的答案。

根据link,异常 pg8000.errors.InterfaceError(Error) 是针对与数据库接口而非数据库本身相关的错误引发的通用异常。例如,如果接口尝试使用 SSL 连接但服务器拒绝,则会引发 InterfaceError。

    检查您是否在项目中启用了服务网络 API。 如果您尝试将私有 IP 地址分配给 Cloud SQL 实例,并且您使用的是共享 VPC,您还需要启用 宿主项目的服务网络 API。

    CSV 和 SQL 格式的导出方式不同。 SQL 格式包括 整个数据库,并且可能需要更长的时间才能完成。采用 CSV 格式并运行多个较小的导出作业以减少 每个操作的大小和长度,以避免导出期间超时。 也许 temp_file_limit 标志对于您的数据库设置得太低 用法。增加 temp_file_limit 大小。见Configuring database flags。

    检查您是否正确地将 sqlalchemy 会话范围限定为 这里描述: https://flask.palletsprojects.com/en/1.1.x/patterns/sqlalchemy/

    具体来说,当使用 scoped_session 时,您不会删除 与 @app.teardown_context 装饰器的会话。

    关注documentation 以查看是否所有清单 您的案例已遇到连接问题。

【讨论】:

以上是关于写入谷歌云 postgresql 数据库的连接网络错误的主要内容,如果未能解决你的问题,请参考以下文章

将节点js连接到postgresql(谷歌云平台)

将谷歌云功能连接到云 sql (postgreSQL)

使用python将数据写入谷歌云存储

Neo4j 在谷歌云 pubsub 订阅中写入事务恐慌

如何从应用引擎将写入附加到谷歌云存储文件?

无法识别的配置参数“默认表访问方式”谷歌云