diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-11-30 12:19:26 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-11-30 12:19:26 -0500 |
commit | 03a3b5ffd3027c79ce9b17b9388fd074e69b889d (patch) | |
tree | 72834b6bc48c6e2435cd745317c30cad023080b0 | |
parent | 8145100da43381007e8683373b3f82fb8c21df86 (diff) | |
download | sqlalchemy-03a3b5ffd3027c79ce9b17b9388fd074e69b889d.tar.gz |
- A descriptive ValueError is now raised in the event that SQL server
returns an invalid date or time format from a DATE or TIME
column, rather than failing with a NoneType error. Pull request
courtesy Ed Avis.
pullreq github:206
-rw-r--r-- | doc/build/changelog/changelog_10.rst | 10 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/mssql/base.py | 12 | ||||
-rw-r--r-- | test/dialect/mssql/test_types.py | 36 |
3 files changed, 53 insertions, 5 deletions
diff --git a/doc/build/changelog/changelog_10.rst b/doc/build/changelog/changelog_10.rst index be0654b84..537f750ca 100644 --- a/doc/build/changelog/changelog_10.rst +++ b/doc/build/changelog/changelog_10.rst @@ -19,6 +19,16 @@ :version: 1.0.10 .. change:: + :tags: bug, mssql + :versions: 1.1.0b1 + :pullreq: github:206 + + A descriptive ValueError is now raised in the event that SQL server + returns an invalid date or time format from a DATE or TIME + column, rather than failing with a NoneType error. Pull request + courtesy Ed Avis. + + .. change:: :tags: bug, py3k :versions: 1.1.0b1 :pullreq: github:210 diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index 487f21df9..1ee328e83 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -533,9 +533,13 @@ class _MSDate(sqltypes.Date): if isinstance(value, datetime.datetime): return value.date() elif isinstance(value, util.string_types): + m = self._reg.match(value) + if not m: + raise ValueError( + "could not parse %r as a date value" % (value, )) return datetime.date(*[ int(x or 0) - for x in self._reg.match(value).groups() + for x in m.groups() ]) else: return value @@ -567,9 +571,13 @@ class TIME(sqltypes.TIME): if isinstance(value, datetime.datetime): return value.time() elif isinstance(value, util.string_types): + m = self._reg.match(value) + if not m: + raise ValueError( + "could not parse %r as a time value" % (value, )) return datetime.time(*[ int(x or 0) - for x in self._reg.match(value).groups()]) + for x in m.groups()]) else: return value return process diff --git a/test/dialect/mssql/test_types.py b/test/dialect/mssql/test_types.py index 6c6ff6841..dad86c60a 100644 --- a/test/dialect/mssql/test_types.py +++ b/test/dialect/mssql/test_types.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -from sqlalchemy.testing import eq_, engines, pickleable +from sqlalchemy.testing import eq_, engines, pickleable, assert_raises_message import datetime import os from sqlalchemy import Table, Column, MetaData, Float, \ @@ -8,8 +8,8 @@ from sqlalchemy import Table, Column, MetaData, Float, \ UnicodeText, LargeBinary from sqlalchemy import types, schema from sqlalchemy.databases import mssql -from sqlalchemy.dialects.mssql.base import TIME, MS_2005_VERSION, \ - MS_2008_VERSION +from sqlalchemy.dialects.mssql.base import TIME, _MSDate +from sqlalchemy.dialects.mssql.base import MS_2005_VERSION, MS_2008_VERSION from sqlalchemy.testing import fixtures, \ AssertsExecutionResults, ComparesTables from sqlalchemy import testing @@ -34,6 +34,36 @@ class TimeTypeTest(fixtures.TestBase): result_processor = mssql_time_type.result_processor(None, None) eq_(expected, result_processor(value)) + def test_result_processor_invalid(self): + mssql_time_type = TIME() + result_processor = mssql_time_type.result_processor(None, None) + assert_raises_message( + ValueError, + "could not parse 'abc' as a time value", + result_processor, 'abc' + ) + + +class MSDateTypeTest(fixtures.TestBase): + + def test_result_processor(self): + expected = datetime.date(2000, 1, 2) + self._assert_result_processor(expected, '2000-01-02') + + def _assert_result_processor(self, expected, value): + mssql_date_type = _MSDate() + result_processor = mssql_date_type.result_processor(None, None) + eq_(expected, result_processor(value)) + + def test_result_processor_invalid(self): + mssql_date_type = _MSDate() + result_processor = mssql_date_type.result_processor(None, None) + assert_raises_message( + ValueError, + "could not parse 'abc' as a date value", + result_processor, 'abc' + ) + class TypeDDLTest(fixtures.TestBase): |