Skip to content

Add iterator support for DbObject with collection content #314

@n8falke

Description

@n8falke

Allowing the usage of DbObject directly in example for-loops, map() or set()-constructor without aslist() to list conversion would simplify usage of from queries returned collections.

Example implementation:

class DbObject:
    ...
    def __iter__(self):
        """
        Return generator iterating over each of the collection’s elements in
        index order.
        """
        self._ensure_is_collection()
        ix = self._impl.get_first_index()
        while ix is not None:
            yield(self._impl.get_element_by_index(ix))
            ix = self._impl.get_next_index(ix)

Example usage with PL/SQL:

...
conn = oracledb.connect(...)
out_type = con.gettype("SYS.DBMS_SQL.VARCHAR2_TABLE")
cur = con.cursor()
out_var = cur.var(out_type, 10)
cur.execute("""
    DECLARE
        tbl SYS.DBMS_SQL.VARCHAR2_TABLE;
    BEGIN
        tbl(0) := 'red';
        tbl(1) := 'blue';
        tbl(2) := 'green';
        :out := tbl;
    END;""", out=out_var )
colors = set(out_var.getvalue())
print(colors)
cur.close()

Example with SELECT:

Prepare DB:

CREATE OR REPLACE TYPE STR_TABLE_T AS TABLE OF VARCHAR2(4000);

Python source:

...
cur.execute("SELECT STR_TABLE_T('first', 'second', 'third') FROM dual")
row = cur.fetchone()
for res in row[0]:
    print(res)
...

With table data a use case could be:

SELECT name, CAST(COLLECT(value) AS STR_TABLE_T) AS entries
  FROM name_value_tab
 GROUP BY name

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions