Python 向 Teradata 批量插入?默认太慢

Python bulk insert to Teradata? Default is too slow

有人要求我提供一个 Python 脚本来读取文件、加载到数据帧并写入 Teradata 中的 table。它可以工作,但是写一个 300 行的 table 需要 3-4 分钟。

现在这对于数据仓库来说是一项很小的工作,我们的 Teradata 在处理大量数据集时工作正常,但我发现等待 3 分钟这个脚本到 运行 太麻烦了。我不认为这是系统问题。

是否有更好的方法将中小型 table 加载到 Teradata 中?如果我们在 SQL 服务器中执行此操作,则需要几秒钟,但我们需要访问的其他一些数据已经存在于 Teradata 中。

主要代码如下所示:

import pandas as pd
from sqlalchemy import create_engine

conn_string = 'teradata://' + user + ':' + passw + '@' + host + '/?authentication=LDAP'
eng = create_engine(conn_string)

# insert into table
df.to_sql(table_name, con = eng, if_exists = 'replace', 
          schema='TEMP', index=False, dtype=df_datatypes)

以上有效,但是当我将 method='multi' 参数添加到 to_sql 时,出现错误:

    CompileError: The 'teradata' dialect with current database version settings does not 
support in-place multirow inserts.

然后我添加了 chunksize=100 并且出现了这个错误:

DatabaseError: [HY000] [Teradata][ODBC Teradata Driver][Teradata Database](-9719)QVCI feature is disabled.

有没有办法加快速度?我应该做一些 Python 之外的事情吗?

佩德罗。我可以同情你。我在一家在 Teradata 中拥有大量数据仓库的组织工作,要使其正常运行几乎是不可能的。我开发了一个 Python (3.9) 脚本,它使用 teradatasql 包来连接 Python/SQLAlchemy,并且运行良好。

此脚本反映了 PostgreSQL 数据库,table-by-table 从 PostgreSQL 中提取数据,将其作为对象保存在 Python 中,然后使用反映的 PostgreSQL tables 在 Teradata 中创建可比较的版本,最后将检索到的数据推送到 tables。

我已经对此进行了质量检查,这是我得到的结果:

  • table PostgreSQL 中的反射时间:平均 0.95 秒
  • 最长的 PostgreSQL 数据检索:4.22 秒
  • 最短 在 Teradata 中创建镜像的时间 tables:12.10 秒
  • 最短 将数据加载到 Teradata 的时间:8.39 秒
  • 最长 将数据加载到 Teradata 的时间:大约。 7,212 秒

这里的重点是 Teradata 是一个糟糕的平台,无法完成关键业务任务。我已经向高级领导证明了 Teradata 相对于其他 5 个 ODBC 的性能,而 Teradata 的性能是最差的。

也许版本 17 的情况更好;但是,我们使用的是版本 16.20.53.30,该版本也不支持就地多行插入。我建议您的组织停止使用 Teradata 并转向功能更强大的产品,例如 Snowflake。 Snowflake 具有出色的 Python 支持和出色的 CLI。

Pedro,如果您试图通过 ODBC 一次加载一行,那么您遇到的问题就像试图通过吸管填满游泳池一样。

Teradata 一直是并行平台。您需要使用批量加载程序——或者,如果您是 Python 粉丝,请使用 teradataml(代码如下)。

顺便说一句,我在笔记本电脑上在 12 秒内加载了 728,000 条记录。当我在 Azure 中构建 Teradata 系统时,我能够使用下面的相同代码在 2 秒内加载相同的 728,000 条记录:

# -*- coding: utf-8 -*-
import pandas as pd
from teradataml import create_context, remove_context
con = create_context(host = <host name or IP address>, username=<username>, password=<password>, database='<#what ever default database you want>')

colnames = ['storeid','custnumber','invoicenumber','amount']

dataDF = pd.read_csv('datafile.csv', delimiter=',', names=colnames, header=None)

copy_to_sql(dataDF, table_name = 'store', if_exists='replace') # this will load the datafrom from your client machine into the Teradata system.

remove_context()