【问题标题】:Python: Iterating through user defined Oracle PL/SQL typesPython:遍历用户定义的 Oracle PL/SQL 类型
【发布时间】:2021-11-25 21:22:46
【问题描述】:

我正在尝试使用完全通过 api 访问的 Oracle 系统(不能直接访问表)。 Oracle 端是这样构建的:

create or replace package Chb_pythontest
  authid definer
as
  type Python_test_rec is record
  (
    Io_var    number,
    Var1      number
  );
  type Python_test_tab is table of Python_test_rec
    index by binary_integer;

  procedure Test_output_collection (Io_id            in     number,
                                    Out_test_table      out Python_test_tab);
end Chb_pythontest;

使用这个 Python 代码可以正常工作:

conn = co.connect(CONN_STR)
with conn.cursor() as cursor:
    collection_type = conn.gettype("CHB_PYTHONTEST.PYTHON_TEST_TAB")
    collection = collection_type.newobject()
    cursor.callproc("Chb_pythontest.Test_output_collection", [1, collection])          

    ix = collection.first()
    while ix is not None:
        record = collection.getelement(ix)
        print("Rownum: ", ix)
        print(">> IO_VAR -> ", record.IO_VAR)
        print(">> VAR1 -> ", record.VAR1)
        ix = collection.next(ix)

它显然知道记录元素中有一个 IO_VAR 和 VAR1,但这只是因为我明确地引用了它们。我发现没有办法动态地迭代它。将其转换为列表或字典将是理想的。

我需要创建自己的迭代器还是可以使用 cx_oracle 或类似工具来完成?

【问题讨论】:

标签: python oracle cx-oracle


【解决方案1】:

可以当前迭代 cx_Oracle 对象属性,但它是一个私有方法,所以它有点像 hack。如果您反省一下cx_Oracle.Object 的话:

dir(collection.getelement(1))

您可以看到所有可用的方法。这里我们感兴趣的是__getattribute__() - 传入一个属性名称,您可以动态获取值,而不是使用object.ATTRIBUTENAME

我们还需要对象类型(在本例中为 IO_VAR 和 VAR1)中的属性名称(“列”)。您可以从collection_type.element_type.attributes 获取它们。

将所有这些放在一起,我们可以在打印循环中运行它,就像您的代码一样:

for r in range(1,collection.size()):
    record = collection.getelement(r)
    print(f"Rownum: {r}")
    for k in collection_type.element_type.attributes:
        print(f">> {k.name} -> {record.__getattribute__(k.name)}")

或者将整个集合变成一个字典列表(使用相当繁琐的列表/字典推导)。

pycollection = [{k.name: collection.aslist()[r].__getattribute__(k.name) for k in collection_type.element_type.attributes} for r in range(collection.size())]
print(pycollection)

如果集合很大,它可能会有点慢;可能有更好的选择,但我不知道。

【讨论】:

  • 感谢您的回答,这似乎与我所寻找的差不多。它确实似乎是一个相当麻烦的解决方案,所以我可能会在 oracle 端解决它,而不是通过使用返回 json 或类似的函数重载它。无论如何,谢谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 2020-12-27
  • 2011-06-11
  • 2013-01-05
  • 2023-03-21
  • 2020-08-01
相关资源
最近更新 更多