Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Expose Cursor.warning_count #1056

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
# Changes

## v1.1.0

Release date: TBD

* Exposed `Cursor.warning_count` to check for warnings without additional query (#1056)

## v1.0.3

Release date: TBD

* Dropped support of end of life MySQL version 5.6
* Dropped support of end of life MariaDB versions below 10.3
* Dropped support of end of life Python version 3.6
* Exposed `Cursor.warning_count` to check for warnings without additional query (#1056)


## v1.0.2
Expand Down
5 changes: 5 additions & 0 deletions pymysql/cursors.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class Cursor:

def __init__(self, connection):
self.connection = connection
self.warning_count = 0
self.description = None
self.rownumber = 0
self.rowcount = -1
Expand Down Expand Up @@ -331,6 +332,7 @@ def _clear_result(self):
self._result = None

self.rowcount = 0
self.warning_count = 0
self.description = None
self.lastrowid = None
self._rows = None
Expand All @@ -341,6 +343,7 @@ def _do_get_result(self):
self._result = result = conn._result

self.rowcount = result.affected_rows
self.warning_count = result.warning_count
self.description = result.description
self.lastrowid = result.insert_id
self._rows = result.rows
Expand Down Expand Up @@ -442,6 +445,7 @@ def fetchone(self):
self._check_executed()
row = self.read_next()
if row is None:
self.warning_count = self._result.warning_count
return None
self.rownumber += 1
return row
Expand Down Expand Up @@ -475,6 +479,7 @@ def fetchmany(self, size=None):
for i in range(size):
row = self.read_next()
if row is None:
self.warning_count = self._result.warning_count
break
rows.append(row)
self.rownumber += 1
Expand Down
33 changes: 31 additions & 2 deletions pymysql/tests/test_SSCursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
try:
from pymysql.tests import base
import pymysql.cursors
from pymysql.constants import CLIENT
from pymysql.constants import CLIENT, ER
except Exception:
# For local testing from top-level directory, without installing
sys.path.append("../pymysql")
from pymysql.tests import base
import pymysql.cursors
from pymysql.constants import CLIENT
from pymysql.constants import CLIENT, ER


class TestSSCursor(base.PyMySQLTestCase):
Expand Down Expand Up @@ -122,6 +122,35 @@ def test_SSCursor(self):
cursor.execute("DROP TABLE IF EXISTS tz_data")
cursor.close()

def test_warnings(self):
con = self.connect()
cur = con.cursor(pymysql.cursors.SSCursor)
cur.execute("DROP TABLE IF EXISTS `no_exists_table`")
self.assertEqual(cur.warning_count, 1)

cur.execute("SHOW WARNINGS")
w = cur.fetchone()
self.assertEqual(w[1], ER.BAD_TABLE_ERROR)
self.assertIn(
"no_exists_table",
w[2],
)

# ensure unbuffered result is finished
self.assertIsNone(cur.fetchone())

cur.execute("SELECT 1")
self.assertEqual(cur.fetchone(), (1,))
self.assertIsNone(cur.fetchone())

self.assertEqual(cur.warning_count, 0)

cur.execute("SELECT CAST('abc' AS SIGNED)")
# this ensures fully retrieving the unbuffered result
rows = cur.fetchmany(2)
self.assertEqual(len(rows), 1)
self.assertEqual(cur.warning_count, 1)


__all__ = ["TestSSCursor"]

Expand Down
20 changes: 18 additions & 2 deletions pymysql/tests/test_cursor.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import warnings

from pymysql.constants import ER
from pymysql.tests import base
import pymysql.cursors

Expand Down Expand Up @@ -129,3 +128,20 @@ def test_executemany(self):
)
finally:
cursor.execute("DROP TABLE IF EXISTS percent_test")

def test_warnings(self):
con = self.connect()
cur = con.cursor()
cur.execute("DROP TABLE IF EXISTS `no_exists_table`")
self.assertEqual(cur.warning_count, 1)

cur.execute("SHOW WARNINGS")
w = cur.fetchone()
self.assertEqual(w[1], ER.BAD_TABLE_ERROR)
self.assertIn(
"no_exists_table",
w[2],
)

cur.execute("SELECT 1")
self.assertEqual(cur.warning_count, 0)
32 changes: 32 additions & 0 deletions pymysql/tests/test_load_local.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from pymysql import cursors, OperationalError, Warning
from pymysql.constants import ER
from pymysql.tests import base

import os
Expand Down Expand Up @@ -63,6 +64,37 @@ def test_unbuffered_load_file(self):
c = conn.cursor()
c.execute("DROP TABLE test_load_local")

def test_load_warnings(self):
"""Test load local infile produces the appropriate warnings"""
conn = self.connect()
c = conn.cursor()
c.execute("CREATE TABLE test_load_local (a INTEGER, b INTEGER)")
filename = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
"data",
"load_local_warn_data.txt",
)
try:
c.execute(
(
"LOAD DATA LOCAL INFILE '{0}' INTO TABLE "
+ "test_load_local FIELDS TERMINATED BY ','"
).format(filename)
)
self.assertEqual(1, c.warning_count)

c.execute("SHOW WARNINGS")
w = c.fetchone()

self.assertEqual(ER.TRUNCATED_WRONG_VALUE_FOR_FIELD, w[1])
self.assertIn(
"incorrect integer value",
w[2].lower(),
)
finally:
c.execute("DROP TABLE test_load_local")
c.close()


if __name__ == "__main__":
import unittest
Expand Down