invokermain / pymssql-utils

A small library that wraps pymssql to make your life easier.
GNU Lesser General Public License v2.1
9 stars 2 forks source link

Add login to handle UUID type in `_get_data_mapper` #13

Closed Feyfeyy closed 3 years ago

Feyfeyy commented 3 years ago

Using python when passing a unique identifier (GUID/UUID) using the query method as an parameter.

the following error is displayed due to no mapping in place for unique identifier (GUID/UUID)

TypeError: a bytes-like object is required, not 'UUID'

as shown the _get_data_mapper method has no sql type hinting for a unique identifier (GUID/UUID) to be mapped which is causing the bug by falling into the clause of _parse_datetimeoffset_from_bytes which is causing the error advised above.

def _get_data_mapper(sql_type_hint: int, item: Any) -> Callable[[Any], Any]:
    if sql_type_hint == 1:  # STRING: str
        if isinstance(item, str):
            return identity

    if sql_type_hint == 2:  # BINARY: bytes, datetime, time, date
        if isinstance(item, datetime):
            return identity
        if isinstance(item, date):
            return identity
        if isinstance(item, time):
            return identity
        try:
            _parse_datetimeoffset_from_bytes(item)
            return _parse_datetimeoffset_from_bytes
        except struct.error:
            # it's not a datetime
            return identity

    if sql_type_hint == 3:  # NUMBER: int, float
        if isinstance(item, int):
            return identity
        if isinstance(item, float):
            return identity

    if sql_type_hint == 4:  # DATETIME: datetime
        if isinstance(item, datetime):
            return identity
invokermain commented 3 years ago

So the problem I can see is that SELECT NEWID() is returned by pymssql as a <class 'uuid.UUID'> object with sql_type_hint 2. So we just need to add this line before the try: statement:

if isinstance(item, uuid.UUID):
    return str(item)
invokermain commented 3 years ago

fix merged in #14