Skip to content

Commit eec53c1

Browse files
Improve fetch performance and fix exception handling in ibm_db_dbi (#1008)
* Improve fetch performance and fix exception handling in ibm_db_dbi Signed-off-by: Balram Choudhary <bchoudhary@rocketsoftware.com>
1 parent b563003 commit eec53c1

2 files changed

Lines changed: 54 additions & 72 deletions

File tree

ibm_db.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1324,7 +1324,7 @@ static int _python_ibm_db_get_result_set_info(stmt_handle *stmt_res)
13241324
}
13251325
}
13261326
LogMsg(DEBUG, "Successfully completed _python_ibm_db_get_result_set_info()");
1327-
LogMsg(INFO, "entry _python_ibm_db_get_result_set_info()");
1327+
LogMsg(INFO, "exit _python_ibm_db_get_result_set_info()");
13281328
return 0;
13291329
}
13301330

ibm_db_dbi.py

Lines changed: 53 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,7 +1242,7 @@ def __enter__(self):
12421242
return self
12431243

12441244
def __exit__(self, exc_type, exc_val, exc_tb):
1245-
return self.close()
1245+
self.close()
12461246

12471247

12481248
# Defines a cursor for the driver connection
@@ -1761,95 +1761,66 @@ def executemany(self, operation, seq_parameters):
17611761
LogMsg(INFO, "exit executemany()")
17621762
return True
17631763

1764-
def _fetch_helper(self, fetch_size=-1):
1765-
"""
1766-
This method is a helper function for fetching fetch_size number of
1767-
rows, after executing an SQL statement which produces a result set.
1768-
It takes the number of rows to fetch as an argument.
1769-
If this is not provided it fetches all the remaining rows.
1770-
"""
1771-
LogMsg(INFO, "entry _fetch_helper()")
1764+
def fetchone(self):
1765+
"""This method fetches one row from the database using the ibm_db.fetchone() API."""
1766+
LogMsg("INFO", "entry fetchone()")
17721767
if self.stmt_handler is None:
1773-
LogMsg(ERROR, "Please execute an SQL statement in order to get a row from result set.")
1768+
LogMsg("ERROR", "Please execute an SQL statement in order to get a row from result set.")
17741769
self.messages.append(
1775-
ProgrammingError("Please execute an SQL statement in order to get a row from result set."))
1776-
raise self.messages[len(self.messages) - 1]
1777-
if not self._result_set_produced:
1778-
LogMsg(ERROR, "The last call to execute did not produce any result set.")
1779-
self.messages.append(ProgrammingError("The last call to execute did not produce any result set."))
1780-
raise self.messages[len(self.messages) - 1]
1781-
row_list = []
1782-
rows_fetched = 0
1783-
while (fetch_size == -1) or \
1784-
(fetch_size != -1 and rows_fetched < fetch_size):
1785-
try:
1786-
row = ibm_db.fetch_tuple(self.stmt_handler)
1787-
except Exception as inst:
1788-
if ibm_db.stmt_errormsg() is not None:
1789-
error_msg = f"Statement error: {str(ibm_db.stmt_errormsg())}"
1790-
LogMsg(ERROR, error_msg)
1791-
self.messages.append(Error(str(ibm_db.stmt_errormsg())))
1792-
raise self.messages[len(self.messages) - 1]
1793-
else:
1794-
LogMsg(ERROR, f"Error occured : {_get_exception(inst)}")
1795-
self.messages.append(_get_exception(inst))
1796-
raise self.messages[len(self.messages) - 1]
1770+
ProgrammingError("Please execute an SQL statement in order to get a row from result set.")
1771+
)
1772+
raise self.messages[-1]
17971773

1798-
if row != False:
1799-
if self.FIX_RETURN_TYPE == 1:
1800-
row_list.append(self._fix_return_data_type(row))
1801-
else:
1802-
row_list.append(row)
1803-
else:
1804-
LogMsg(DEBUG, f"Returning {row_list} from _fetch_helper()")
1805-
LogMsg(INFO, "exit _fetch_helper()")
1806-
return row_list
1807-
rows_fetched = rows_fetched + 1
1808-
LogMsg(DEBUG, f"Returning {row_list} from _fetch_helper()")
1809-
LogMsg(INFO, "exit _fetch_helper()")
1810-
return row_list
1811-
1812-
def fetchone(self):
1813-
"""This method fetches one row from the database, after
1814-
executing an SQL statement which produces a result set.
1774+
if not self._result_set_produced:
1775+
LogMsg("ERROR", "The last call to execute did not produce any result set.")
1776+
self.messages.append(
1777+
ProgrammingError("The last call to execute did not produce any result set.")
1778+
)
1779+
raise self.messages[-1]
18151780

1816-
"""
1817-
LogMsg(INFO, "entry fetchone()")
1818-
LogMsg(INFO, "Fetching one row from the database.")
1819-
row_list = self._fetch_helper(1)
1820-
if len(row_list) == 0:
1821-
LogMsg(DEBUG, "No rows fetched.")
1822-
else:
1823-
LogMsg(DEBUG, "Row fetched successfully.")
1824-
if len(row_list) == 0:
1825-
LogMsg(INFO, "exit fetchone()")
1826-
return None
1781+
row = ibm_db.fetchone(self.stmt_handler)
1782+
if row is None:
1783+
LogMsg("DEBUG", "No rows fetched.")
18271784
else:
1828-
LogMsg(INFO, "exit fetchone()")
1829-
return row_list[0]
1785+
LogMsg("DEBUG", "Row fetched successfully.")
1786+
1787+
LogMsg("INFO", "exit fetchone()")
1788+
return row
18301789

18311790
def fetchmany(self, size=0):
18321791
"""This method fetches size number of rows from the database,
18331792
after executing an SQL statement which produces a result set.
1834-
It takes the number of rows to fetch as an argument. If this
1835-
is not provided it fetches self.arraysize number of rows.
1793+
It takes the number of rows to fetch as an argument. If this
1794+
is not provided, it fetches self.arraysize number of rows.
18361795
"""
18371796
LogMsg(INFO, "entry fetchmany()")
18381797
message = f"Fetching {size} rows from the database."
18391798
LogMsg(DEBUG, message)
1799+
18401800
if not isinstance(size, int_types):
18411801
LogMsg(EXCEPTION, "fetchmany expects argument type int or long.")
18421802
self.messages.append(InterfaceError("fetchmany expects argument type int or long."))
1843-
raise self.messages[len(self.messages) - 1]
1803+
raise self.messages[-1]
1804+
18441805
if size == 0:
18451806
size = self.arraysize
18461807
if size < -1:
18471808
LogMsg(ERROR, "fetchmany argument size expected to be positive")
18481809
self.messages.append(ProgrammingError("fetchmany argument size expected to be positive."))
1849-
raise self.messages[len(self.messages) - 1]
1810+
raise self.messages[-1]
1811+
1812+
if self.stmt_handler is None:
1813+
LogMsg(ERROR, "Please execute an SQL statement in order to get rows from result set.")
1814+
self.messages.append(ProgrammingError("Please execute an SQL statement in order to get rows from result set."))
1815+
raise self.messages[-1]
18501816

1851-
fetch_nrows = self._fetch_helper(size)
1852-
nrows = len(fetch_nrows)
1817+
if not self._result_set_produced:
1818+
LogMsg(ERROR, "The last call to execute did not produce any result set.")
1819+
self.messages.append(ProgrammingError("The last call to execute did not produce any result set."))
1820+
raise self.messages[-1]
1821+
1822+
fetch_nrows = ibm_db.fetchmany(self.stmt_handler, size)
1823+
nrows = len(fetch_nrows) if fetch_nrows else 0
18531824
message = f"Fetched {nrows} rows successfully."
18541825
LogMsg(DEBUG, message)
18551826
LogMsg(INFO, "exit fetchmany()")
@@ -1861,8 +1832,19 @@ def fetchall(self):
18611832
"""
18621833
LogMsg(INFO, "entry fetchall()")
18631834
LogMsg(INFO, "Fetching all remaining rows from the database.")
1864-
rows_fetched = self._fetch_helper()
1865-
nrows = len(rows_fetched)
1835+
1836+
if self.stmt_handler is None:
1837+
LogMsg(ERROR, "Please execute an SQL statement in order to get rows from result set.")
1838+
self.messages.append(ProgrammingError("Please execute an SQL statement in order to get rows from result set."))
1839+
raise self.messages[-1]
1840+
1841+
if not self._result_set_produced:
1842+
LogMsg(ERROR, "The last call to execute did not produce any result set.")
1843+
self.messages.append(ProgrammingError("The last call to execute did not produce any result set."))
1844+
raise self.messages[-1]
1845+
1846+
rows_fetched = ibm_db.fetchall(self.stmt_handler)
1847+
nrows = len(rows_fetched) if rows_fetched else 0
18661848
LogMsg(DEBUG, f"Fetched {nrows} rows successfully.")
18671849
LogMsg(INFO, "exit fetchall()")
18681850
return rows_fetched
@@ -1951,4 +1933,4 @@ def __enter__(self):
19511933
return self
19521934

19531935
def __exit__(self, exc_type, exc_val, exc_tb):
1954-
return self.close()
1936+
self.close()

0 commit comments

Comments
 (0)