首页 > 编程问答 >将非常大的数据插入 PostgreSQL 表的更好方法

将非常大的数据插入 PostgreSQL 表的更好方法

时间:2024-07-25 12:01:35浏览次数:13  
标签:python django postgresql

将非常大的数据插入 PostgreSQL 表的更好方法是什么?
操作系统:Ubuntu 22.04 LTS
数据库:PostgreSQL 14
框架:Python 3.11 Django

现在我使用 insert into 语句一次 100,000 行。平均插入1,000,000行整个过程需要2分钟,在我可以接受的范围内。但我想知道是否有更好的方法来做到这一点。

它工作正常,但不知怎的,它花费了更多时间,有时会出现类似错误

OperationalError: (psycopg2.OperationalError) server closed the connection unexpectedly
from django.db import connection
cursor = connection.cursor()

batch_size = 100000

offset = 0
while True:
    transaction_list_query = SELECT * FROM {source_table} LIMIT {batch_size} OFFSET {offset};  
    cursor.execute(transaction_list_query)
    transaction_list = dictfetchall(cursor)
    if not transaction_list:
        break
    data_to_insert = []
    for transaction in transaction_list:
        # Some Process Intensive Calculations

    insert_query = INSERT INTO {per_transaction_table} ({company_ref_id_id_column}, {rrn_column},{transaction_type_ref_id_id_column}, {transactionamount_column}) VALUES  {",".join(data_to_insert)} ON CONFLICT ({rrn_column}) DO UPDATE SET {company_ref_id_id_column} = EXCLUDED.{company_ref_id_id_column};
    cursor.execute(insert_query)
    offset += batch_size

当前的批量插入方法对于 PostgreSQL 来说已经是一个不错的开始。但是,有一些方法可以优化它并潜在地解决“服务器意外关闭连接”错误:

1. 增加批量大小:

  • 正在使用 100,000 行的批量大小。虽然这通常是一个不错的起点,但尝试增加此值(例如,500,000 或 1,000,000)并衡量性能影响可能会有所帮助。更大的批量可以减少往返于数据库的次数,从而提高效率。

2. 使用 COPY 命令(如果可能):

  • COPY 命令是将数据导入 PostgreSQL 的最快方法。如果能够以文件形式获取数据(例如,CSV 文件),则可以使用 COPY 命令直接将数据加载到表中。这比使用 INSERT 语句要快得多,尤其是在处理大型数据集时。
  • 如果源数据已经在一个表中,可以使用 COPY 将数据导出到一个文件,然后再将它导入到目标表中。

3. 禁用自动提交并手动管理事务:

  • 默认情况下,Django 会为每个查询打开和关闭一个事务。在大型插入操作期间,这可能会导致性能下降。可以通过禁用自动提交并手动管理事务来优化此过程。 ```python from django.db import transaction

    with transaction.atomic(): cursor = connection.cursor() # ... your insertion logic here ... `` * transaction.atomic()` 将确保所有插入操作都在单个事务中执行,从而减少开销。

4. 优化 ON CONFLICT 子句:

  • 虽然的 ON CONFLICT 子句看起来不错,但确保实际需要它至关重要。如果不需要更新重复的行,则删除此子句可以提高性能。

5. 检查连接参数:

  • OperationalError: (psycopg2.OperationalError) server closed the connection unexpectedly 错误可能表示数据库连接问题。检查的 PostgreSQL 服务器日志以获取有关此错误的更多特定信息。
  • 确保的连接参数(例如 connect_timeout keepalives keepalives_idle )已正确配置,以防止连接在长时间运行的操作期间超时。

6. 考虑异步插入:

  • 对于更高级的用例,可以探索使用异步库(如 asyncio 或 Celery)在后台执行插入操作。这使的主应用程序可以继续运行,而不会被插入操作阻塞。

代码示例(使用 COPY 命令):

import psycopg2

# ... 连接到的数据库 ...

with open("your_data.csv", "r") as file:
    with connection.cursor() as cursor:
        cursor.copy_expert(
            """
            COPY per_transaction_table (company_ref_id_id_column, rrn_column, transaction_type_ref_id_id_column, transactionamount_column) 
            FROM STDIN 
            WITH (FORMAT CSV, HEADER);
            """,
            file
        )
        connection.commit()

请记住 在实现任何这些优化后对代码进行基准测试,以衡量它们对特定用例的影响。

标签:python,django,postgresql
From: 77764734

相关文章

  • 如何使用 Python 从 Square 中的创建客户方法中检索客户 ID
    我正在square创建一个客户并得到如下结果。我需要的是获取客户的id。我的代码:fromsquare.clientimportClientclient=Client(access_token=settings.SQUARE_ACCESS_TOKEN,environment=settings.SQUARE_ENVIRONMENT,)api_customers=client.customers......
  • 为什么从.导入Python
    我使用的存储库的结构如下:在myrepo/src/中有:主要.pycore.py和somepkgsomepkg有init.py和其他python文件。somepkg不是任何文件中的类或函数。在main.py中,我看到:from.importcorefrom.importsomepkg我的问题是from和.......
  • Django request.data.get传送列表
    request.data.get('fa_no',[])代码片段通常用于Django处理视图中的传入请求数据。这一行代码试图从请求数据中获取键'fa_no'关联的值。如果在请求数据中未找到'fa_no',它会返回一个默认值空列表([])。以下是每个部分的解释:request:这是HTTP请求对象。data:这个属......
  • 使用 Python 中的 Square API 检索客户 ID
    我正在为Square开发一个客户创建表单,它将创建一个客户,然后立即检索他们的ID以在程序中进一步使用。但是,我不知道如何使用API来过滤使用list_customers命令返回的数据。我找到了这篇文章:HowtoretrievecustomeridfromcreatecustomermethodinSquareusing......
  • Django 自动将作者分配给创建帖子的用户
    我的作者被自动分配时遇到问题,它以前可以工作,但自从我添加了一些内联表单集后就停止工作了-这是我的模型:classRecipe(models.Model):title=models.CharField(max_length=100)description=models.TextField()author=models.ForeignKey(User,on_delet......
  • Django DRF安装设置 序列化器ModelSerializer 视图ModelViewSet 路由url 串讲
    在DjangoRESTFramework(DRF)中,重新编写API视图通常涉及几个步骤。以下是一个简单的示例,展示如何定义和注册视图集、序列化器和路由,以便你可以创建、读取、更新和删除(CRUD)数据。1.定义序列化器#serializers.pyfromrest_frameworkimportserializersfrom.models......
  • Django 你不知道的filterset_fields和filter_fields区别
    filter_fields和filterset_fields是DjangoRESTframework(DRF)中用于过滤的两个不同概念:filter_fields定义:在DRF的ModelViewSet中,filter_fields允许你指定可用于过滤的字段。用法:你可以在视图中设置这个属性,来指定哪些字段可以用于过滤。例如,如果你有一个模型......
  • 如何通过在字符串中使用 \u 或 \U 转义来正确表示 python3 (3.6.1+) 中的补充 unico
    最近我正在学习python,在python3中遇到了unicode转义文字的问题。似乎像Java一样,\u转义被解释为Java使用的UTF-16代码点,但问题来了:例如,如果我尝试放置3个字节的utf-8字符,例如“♬”(https://unicode-table.com/en/266C/),甚至是补充unicode字符,例如“......
  • 我的 Python 代码和 Cycle Time 小部件之间的平均周期时间不同
    我过去遇到过如何在周期时间小部件中计算平均周期时间的一些问题,因此我决定使用Python进行分析,看看是否找到任何方法来计算平均周期时间并获得相同的结果周期时间小部件中显示的值。我的问题是我无法达到周期时间小部件中显示的相同的平均周期时间值。你们能帮我解决这......
  • python3之requests库使用
    使用https://www.cnblogs.com/caroline2016/p/17007956.html建立的api测试下requests库怎么使用。模拟登录时laravelapi那边出现了 Sessionstorenotsetonrequest.错误。解决办法在app/Http/Kernel.php中api中间件组中添加两行代码:<?phpprotected$middlewareGrou......