使用SQLAlchemy的Oracle XML标记

j1dl9f46  于 2022-11-03  发布在  Oracle
关注(0)|答案(2)|浏览(152)

我有一个列聚合方案,其中结果可能超过4000个字符,因此我尝试从listagg切换到xmlagg
下面是我现在拥有的按预期工作的程序:

func.listagg(aggregator, separator).within_group(*order_by)

但是,我在SQLAlchemy documentation中找不到任何xmlagg的示例。

func.rtrim(func.xmlagg(func.xmlelement(e, column, separator)).extract('//text()').getclobval(), separator)

会导致此错误,这是可以理解的:
未捕获的错误:'Function'对象和'Comparator'对象都没有属性'extract'
在SQLAlchemy中支持xmlagg吗?我使用的版本是1.4.29。

nbysray5

nbysray51#

SQLAlchemy中是否支持xmlagg?
像其他函数一样,它应该与SQLAlchemy一起使用。

>>> from sqlalchemy import func, select
>>>
>>> f1 = func.xmlagg(func.xmlelement("foo_tag", "foo_column_aggregator", 'foo_separator'))
>>>
>>> print(select(f1))
SELECT xmlagg(xmlelement(:xmlelement_1, :xmlelement_2, :xmlelement_3)) AS xmlagg_1

Oracle xmlagg函数返回Oracle xmltype(它既不是varchar类型,也不是clob类型)。
在Oracle SQL中:

SQL> SELECT xmlagg(XMLELEMENT("foo_tag",foo,';'))
  2  FROM
  3  (
  4  SELECT 'A1' AS foo FROM dual
  5  UNION ALL SELECT 'A2' AS foo FROM dual
  6  UNION ALL SELECT 'A3' AS foo FROM dual
  7  )
  8  ;

XMLAGG(XMLELEMENT("FOO_TAG",FOO,';'))
--------------------------------------------------------------------------------
<foo_tag>A1;</foo_tag><foo_tag>A2;</foo_tag><foo_tag>A3;</foo_tag>

这部分.extract('//text()').getclobval()是Oracle xmltype的方法。它更像NOSQL语法(或Oracle DB对XML语法的支持),而不是原始SQL语法,因此SQLAlchemy不支持它(可能有相同的扩展,但我没有找到)。在Oracle中,它将是:

SQL> SELECT xmlagg(XMLELEMENT("foo_tag",foo,';')).extract('//text()').getclobval()
  2  FROM
  3  (
  4  SELECT 'A1' AS foo FROM dual
  5  UNION ALL SELECT 'A2' AS foo FROM dual
  6  UNION ALL SELECT 'A3' AS foo FROM dual
  7  )
  8  ;

XMLAGG(XMLELEMENT("FOO_TAG",FOO,';')).EXTRACT('//TEXT()').GETCLOBVAL()
--------------------------------------------------------------------------------
A1;A2;A3;

您可以选择:
1.在Python中使用xml(在Python中像这样解析xml <foo_tag>A1;</foo_tag><foo_tag>A2;</foo_tag><foo_tag>A3;</foo_tag>
1.在Oracle中编写一个函数来转换XML格式的数据--然后在python中调用它。
Meaby是这样的:

SQL> CREATE OR REPLACE FUNCTION extract_from_xmlagg (a_xml IN xmltype) RETURN clob
  2  AS
  3  v_clob clob;
  4  BEGIN
  5  SELECT xmlcast(a_xml AS clob)
  6  INTO v_clob
  7  FROM dual;
  8  RETURN v_clob;
  9  END;
 10  /

Function created.

SQL> SELECT extract_from_xmlagg(XMLAGG(XMLELEMENT("foo_tag",foo,';')))
  2  FROM
  3  (
  4  SELECT 'A1' AS foo FROM dual
  5  UNION ALL SELECT 'A2' AS foo FROM dual
  6  UNION ALL SELECT 'A3' AS foo FROM dual
  7  )
  8  ;
EXTRACT_FROM_XMLAGG(XMLAGG(XMLELEMENT("FOO_TAG",FOO,';')))
--------------------------------------------------------------------------------
A1;A2;A3;

SQL>

1.查找或编写SQLAlchemy的扩展。

frebpwbc

frebpwbc2#

我不熟悉SQLAlchemy。但是,extract是一个(不推荐使用的)Oracle SQL函数。因此,您可以尝试将func.xmlagg的结果 Package 在对func.extract的调用中。该结果可能还需要 Package 在对**xmltype.getclobval()**的调用中。

func.rtrim(func.xmltype(func.extract(func.xmlagg(func.xmlelement(e, column, separator)), '//text()')).getclobval())

相关问题