denisenkom / pytds

Python DBAPI driver for MSSQL using pure Python TDS (Tabular Data Stream) protocol implementation
MIT License
191 stars 53 forks source link

Cannot fetch results ("InterfaceError: Invalid type id 240") #65

Closed josePhoenix closed 7 years ago

josePhoenix commented 7 years ago

I'm trying to use pytds with a Microsoft SQL Server 2012 database containing a table with a column of type geometry. Trying to fetch the results of a query including that column results in: InterfaceError: ('Invalid type id', 240). The ID 240 corresponds to the system_type_id for the geometry and geography types in sys.types, so I suspect the geometry column is the culprit.

(For what it's worth, pymssql seems to handle this query, though perhaps not in a very friendly way.)

With this code:

c.execute("SELECT TOP 1 * FROM CaomPlane;")
c.fetchall()
---------------------------------------------------------------------------
InterfaceError                            Traceback (most recent call last)
<ipython-input-81-6c71b5cabee4> in <module>()
----> 1 c.execute("SELECT TOP 1 * FROM CaomPlane;")
      2 c.fetchall()

/Users/jlong/lib/python3.6/site-packages/pytds/__init__.py in execute(self, operation, params)
    627         conn = self._assert_open()
    628         conn._try_activate_cursor(self)
--> 629         self._execute(operation, params)
    630 
    631     def _begin_tran(self, isolation_level):

/Users/jlong/lib/python3.6/site-packages/pytds/__init__.py in _execute(self, operation, params)
    616         else:
    617             self._exec_with_retry(lambda: self._session.submit_plain_query(operation))
--> 618         self._session.find_result_or_done()
    619         self._setup_row_factory()
    620 

/Users/jlong/lib/python3.6/site-packages/pytds/tds.py in find_result_or_done(self)
   3802             marker = self.get_token_id()
   3803             if marker == TDS7_RESULT_TOKEN:
-> 3804                 self.process_token(marker)
   3805                 return True
   3806             elif marker in (TDS_DONE_TOKEN, TDS_DONEPROC_TOKEN, TDS_DONEINPROC_TOKEN):

/Users/jlong/lib/python3.6/site-packages/pytds/tds.py in process_token(self, marker)
   3737         if not handler:
   3738             self.bad_stream('Invalid TDS marker: {0}({0:x})'.format(marker))
-> 3739         return handler(self)
   3740 
   3741     def get_token_id(self):

/Users/jlong/lib/python3.6/site-packages/pytds/tds.py in <lambda>(self)
   3854     TDS_CAPABILITY_TOKEN: lambda self: self.process_msg(TDS_CAPABILITY_TOKEN),
   3855     TDS_PARAM_TOKEN: lambda self: self.process_param(),
-> 3856     TDS7_RESULT_TOKEN: lambda self: self.tds7_process_result(),
   3857     TDS_ROW_TOKEN: lambda self: self.process_row(),
   3858     TDS_NBC_ROW_TOKEN: lambda self: self.process_nbcrow(),

/Users/jlong/lib/python3.6/site-packages/pytds/tds.py in tds7_process_result(self)
   2709             curcol = Column()
   2710             info.columns.append(curcol)
-> 2711             self.get_type_info(curcol)
   2712 
   2713             #

/Users/jlong/lib/python3.6/site-packages/pytds/tds.py in get_type_info(self, curcol)
   2669         type_class = self._tds._type_map.get(type_id)
   2670         if not type_class:
-> 2671             raise InterfaceError('Invalid type id', type_id)
   2672         curcol.type = type_class.from_stream(r)
   2673 

InterfaceError: ('Invalid type id', 240)

For comparison, I tried pymssql:

c.execute("SELECT TOP 1 * FROM CaomPlane;")
c.fetchall()

[(1000000000,
  1000000000,
  '2391589660720627712',
  'PUBLIC',
  datetime.datetime(2012, 2, 2, 22, 24, 14),
  'PUBLIC',
  datetime.datetime(2012, 2, 2, 22, 24, 14),
  'image',
  2,
  'http://galex.stsci.edu/data/GR7/pipe/01-vsn/02437-NGA_NGC5398_580_F5_19_158/d/01-main/0007-img/07-try/qa/NGA_NGC5398_580_F5_19_158-xd-int_2color.jpg',
  None,
  'NGS',
  None,
  None,
  'NGS',
  'CALTECH',
  None,
  None,
  None,
  None,
  210.542232477159,
  -32.6804067553693,
  b'A\x96\x01\x00\x01\x04&\x00\x00\x00\xb9\xc4O\xeb\xcfV@\xc0\xe1C\x89\x96\x1cij@\x9d\xa4T\x1dMI@\xc0A\xa1\x1a\x06\xbehj@\xa5k\xc3\xb41<@\xc0\xf4x\xce\xd4\xb3gj@A\x04$\xb3\xdd/@\xc0\xee\xb8<1\x06fj@\xb4\xf0\x8a\x1a\xab$@\xc0\xe9\x1a\x1c\xdb\xc1cj@\xd5#\rn\xeb\x1a@\xc0\x04\xa7\xa1\xba\xf7`j@1\xc5$u\xe5\x12@\xc0Q~Z^\xbc]j@X`]O\xd3\x0c@\xc0|\xb9\xecc\'Zj@K\x06\xdb\xe3\xe0\x08@\xc02\xe3\xd0\xcfRVj@ }\xb4\xb4*\x07@\xc0"\xf4\x1aXZRj@X\x87\xab\x1c\xbd\x07@\xc0\x8df\x9f\xa6ZNj@\x14\xa1\t\xfb\x93\n@\xc0\xa7\x020\x96pJj@F\xf8\x0f\xd0\x9a\x0f@\xc0\x11\xb5\xe1n\xb8Fj@\x18\xb4\x0cH\xad\x16@\xc0\xa3\xc0L%MCj@\x94\xf2\xbd3\x98\x1f@\xc0\x84\xb6b\xa0G@j@\xferw\xe7\x1a*@\xc0\xf1\x1bW\n\xbe=j@\xdc\xaf+\xfb\xe85@\xc0\x15\x87;0\xc3;j@fA0`\xacB@\xc0\xe7\xbb\xc6\xf4e:j@\xcc\x87\x14\xc1\x07P@\xc0\xfa\x86x\xda\xb09j@p\xe4G\x1d\x99]@\xc0q\x7f&\xa9\xa99j@\x1a\xb1G\x8f\xfcj@\xc0\x8b\x0f\x1e3Q:j@\xae\x11\xa0*\xcfw@\xc0A\xea\x1b=\xa3;j@\xabJ2\xdd\xb1\x83@\xc0\x08.\x03\x8c\x96=j@\xd3ZE=L\x8e@\xc03G\xc1\x19\x1d@j@\xe9b\x91.O\x97@\xc0\xa9y\x1ar$Cj@\xc9`\xdeFw\x9e@\xc0^\\\x915\x96Fj@o\xc1)\xde\x8e\xa3@\xc0\x10K\xda\xbfXJj@\xd33\x9c\xb6o\xa6@\xc0\xa7]\xa7\xecONj@u\x84_,\x04\xa7@\xc0\x8a\x98L\xf4]Rj@d\xad\xc2\xe2G\xa5@\xc05c\x8fXdVj@\xf9\xd74\xe7G\xa1@\xc0\xb2\x16<\xd8DZj@*\xd1iH"\x9b@\xc0L\xf0\x97`\xe2]j@\xda\xc0F\'\x05\x93@\xc0\xfbn\x04\xf3!aj@\x90\x80\xb8H-\x89@\xc0E\xe4\xcbv\xebcj@2\xfd\xb77\xe4}@\xc0\xb6\xe7do*fj@\x9c\x81\x99\x08~q@\xc0\x06V\xa3\x91\xcegj@\xdf\xa6\xdc\xd0Vd@\xc0\xc1\xb2\xca3\xcchj@\xb9\xc4O\xeb\xcfV@\xc0\xe1C\x89\x96\x1cij@\x01\x00\x00\x00\x02\x00\x00\x00\x00\x01\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x03',
  'CIRCLE ICRS 210.54223248 -32.68040676 0.625',
  3840,
  3840,
  None,
  1.5,
  None,
  235.0,
  169.3,
  300.7,
  b'\x00\x00\x00\x00\x01\x14\x9a\x99\x99\x99\x99)e@\x00\x00\x00\x00\x00\x00\x00\x0033333\xcbr@\x00\x00\x00\x00\x00\x00\x00\x00',
  'RANGE 169.3 300.7',
  None,
  None,
  None,
  None,
  'NUV',
  'UV',
  None,
  None,
  None,
  52797.213206,
  52797.21005787037,
  52797.21635416667,
  b'\x00\x00\x00\x00\x01\x14\x08\x8e\xcb\xb8\xa6\xc7\xe9@\x00\x00\x00\x00\x00\x00\x00\x00K9_\xec\xa6\xc7\xe9@\x00\x00\x00\x00\x00\x00\x00\x00',
  'RANGE 52797.210058 52797.216354',
  1,
  544.0,
  544.0,
  544.0,
  None,
  None,
  None,
  None,
  None,
  None,
  None,
  None,
  datetime.datetime(2015, 8, 9, 19, 20, 55, 507000),
  datetime.datetime(2016, 8, 25, 20, 7, 41, 833000),
  -1)]
josePhoenix commented 7 years ago

Further digging turned up https://msdn.microsoft.com/en-us/library/ee320529.aspx

Here's a text version of the Wireshark capture of the response. I have the pcapng file as well if that would help.