在 cx_Oracle 上执行许多 CLOB 元素

发布于 2024-11-09 18:01:30 字数 686 浏览 0 评论 0原文

我有一个函数可以将一大块数据插入到oracle 数据库中。我试图通过使用executemany 来实现这一点。

我的函数如下所示:

  def InsertChunk(self):
    try:
      if len(self.list_dict_values) >= self.chunksize:
        self.db.cursor.executemany(
          str(self.insert_sql),
          self.list_dict_values
         )
        self.list_dict_values = []
    except cx_Oracle.Error, e:
      print e

该函数被许多表使用,如果这些表中没有 CLOB 列,则该函数可以正常工作。仅当 chunksize 设置为 1 或 2 时,它才适用于具有 CLOB 列的表。有时它适用于 3,但大多数情况下不起作用。当块大小为 4 时,我什至让它工作了一次。我使用此函数将块大小设置为 1000 左右,以加快该过程。

当 chunksize 设置为 3 时,有时会返回以下错误:

ORA-24813: 无法发送或接收不支持的 LOB。

有时它会说已中止并停止脚本。

知道为什么这个脚本每次使用相同的参数运行时都有不同的行为吗?

I have a function that inserts a chunk of data into oracle database. I'm trying to achieve this by using executemany.

My function looks like this:

  def InsertChunk(self):
    try:
      if len(self.list_dict_values) >= self.chunksize:
        self.db.cursor.executemany(
          str(self.insert_sql),
          self.list_dict_values
         )
        self.list_dict_values = []
    except cx_Oracle.Error, e:
      print e

This function is used by many tables and works fine if those tables don't have a CLOB column in them. It works on tables with CLOB columns only when chunksize is set to 1 or 2. Sometimes it works on 3, but most of the time it doesn't. I even got it working once when the chunksize was 4. I'm using this function to set the chunk size to something around 1000 to speed up the process.

When the chunksize is set to 3, sometimes it returns the following error:

ORA-24813: cannot send or receive an unsupported LOB.

And sometimes it says aborted and stops the script.

Any idea why this script has a different behavior every time it is run with the same parameters?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

故人如初 2024-11-16 18:01:30

我也有同样的问题。就我而言,这是由于错误使用 cx_Oracle 变量类型造成的。当填写我的 list_dict_values 等价物时,我正在做这样的事情:

for row in list_dict_values:
  for key, val in row.iteritems():
     v = cursor.var(cx_Oracle.CLOB)
     v.setvalue(0, val)
     row[key] = v
..
InsertChunk()

您需要创建一个具有数组大小的单个变量,而不是许多小变量,然后在字典的每一行中引用它。

lobdict = {}
for k in list_dict_vals[0].keys():
   lobdict[k] = cursor.var(cx_Oracle.CLOB, arraysize=len(list_dict_vals))
for rownum, row in enumerate(list_dict_values):
  for key, val in row.iteritems():
     lob = lobdict[key]
     lob.setvalue(rownum, val)
     row[key] = lob
...
InsertChunk()

将每一行设置为相同的值似乎很奇怪,但它是有效的 - 在内部,oracle 代码想要迭代指针列表,所以这就是您需要做的。

I had the same problem. In my case it was caused by using the cx_Oracle variable types incorrectly. When filling out my equivalent of list_dict_values I was doing something like this:

for row in list_dict_values:
  for key, val in row.iteritems():
     v = cursor.var(cx_Oracle.CLOB)
     v.setvalue(0, val)
     row[key] = v
..
InsertChunk()

Instead of many small variables, you need to create a single variable with an arraysize, then reference it in every row of your dict.

lobdict = {}
for k in list_dict_vals[0].keys():
   lobdict[k] = cursor.var(cx_Oracle.CLOB, arraysize=len(list_dict_vals))
for rownum, row in enumerate(list_dict_values):
  for key, val in row.iteritems():
     lob = lobdict[key]
     lob.setvalue(rownum, val)
     row[key] = lob
...
InsertChunk()

It seems weird to set every row to the same value, but it works - internally the oracle code wants to iterate through a list of pointers, so that's what you need to make.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文