【问题标题】:Best way to handle large amount of inserts to Azure SQL database using TypeORM使用 TypeORM 处理对 Azure SQL 数据库的大量插入的最佳方法
【发布时间】:2021-03-19 15:02:39
【问题描述】:

我有一个使用 Azure Functions (TypeScript) 创建的 API。这些函数接收 JSON 数据数组,将它们转换为 TypeORM 实体并将它们插入 Azure SQL 数据库。我最近遇到了一个问题,数组有数百个项目,我得到了一个错误:

The incoming request has too many parameters. The server supports a maximum of 2100 parameters. Reduce the number of parameters and resend the request

我认为使用实体管理器一次保存所有数据会导致问题:

const connection = await createConnection();
connection.manager.save(ARRAY OF ENTITIES);

处理此问题的最佳可扩展解决方案是什么?我有几个想法,但我不知道它们是否有用,尤其是性能方面。

  1. 开始事务 -> 开始在 forEach 循环中单独保存实体 -> 提交
  2. 将数组拆分为较小的数组 -> 开始事务 -> 单独保存较小的数组 -> 提交
  3. 还有别的吗?

目前数组大小为几十个或几百个,但偶尔也有可能包含 10k+ 个元素的数组。

【问题讨论】:

  • 使用表值参数。不知道如何从 Azure Functions 中做到这一点

标签: sql-server azure-functions azure-sql-database typeorm


【解决方案1】:

实现大规模扩展的一种方法是让 DB 来处理这个问题。例如。使用外部表。 DB 进行解析。让您的代码只进行编排。

例如

  1. 使要插入的数据在 ADLS (Datalake) 中可用:
    • 调用者不会使用所有数据(在正文或查询参数中作为数组)调用 REST API,而是将数据作为 csv/json/parquet/... 文件写入 ADLS 位置。或
    • 调用者保持不变。您的 Azure 函数将数据写入 ADLS 位置中的某个 csv/json/parquet/... 文件(而不是写入 DB)。
  2. 让 DB 从 ADLS 读取和加载数据。

查看格式supported by EXTERNAL FILE FORMAT

您无需每次都删除并重新创建外部表。每当您在其上运行SELECT 时,DB 都会解析 ADLS 中的数据。但这是一种选择。

【讨论】:

  • 感谢您的回复,一个非常有趣的方法!如果在某些时候需要大规模扩展,我会记住这一点。
【解决方案2】:

我最终以简单的方式做到了这一点,因为 TypeORM 已经提供了分块保存的能力。这可能不是最理想的方式,但至少我摆脱了“参数过多”的错误。

// Save all data in chunks of 100 entities
connection.manager.save(ARRAY OF ENTITIES, { chunk: 100 });

【讨论】:

    猜你喜欢
    • 2013-11-11
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 2020-12-19
    相关资源
    最近更新 更多