On 10/05/2016 12:38 AM, Jonathan Schultz wrote:
> Many thanks for the prompt reply.
>
> if you are getting that error on INSERT it sounds like there are driver
> issues involved (e.g. pymssql, pyodbc). For an INSERT you should not
> get that error; using the VARBINARY SQLAlchemy type, SQLAlchemy calls
> upon a construct provided by your DBAPI (e.g., the driver) called
> Binary(). This is a wrapper that is intended to signal to the driver
> that this value is not a character string, it's bytes. Internally the
> driver should be doing this step.
>
> For here we'd look to see what driver you're using, if changing drivers
> resolves, and as always a small and self-contained reproducing test
> case. For a driver issue I'd then look to convert the test case to be
> using the DB driver alone, then we send a bug report to that driver.
>
>
> OK in brief I'm using pymssql. I've never used pyodbc but if it's worth
> investigating whether it produces the same error I'll find the time to
> figure out how to use it.
pymssql is overall a much better driver these days as it is actively
maintained, pyodbc seems like it isn't maintained very often.
However, for this one, pymssql is failing and pyodbc isn't, so I'd
advise reporting this upstream to the pymssql driver. See attached. As
a workaround, you can supply CONVERT yourself as part of the datatype:
from sqlalchemy import *
e = create_engine("mssql+pymssql://
scott:ti...@192.168.122.135:1213",
echo=True)
class MyVarBinary(TypeDecorator):
impl = VARBINARY
def bind_expression(self, bindvalue):
return cast(bindvalue, VARBINARY)
m = MetaData()
t = Table(
'test', m,
Column('id', Integer, primary_key=True),
Column('x', MyVarBinary())
)
conn = e.connect()
trans = conn.begin()
t.create(conn)
conn.execute(
t.insert().values({'x':bindparam('x')}),
{'x': b'a'}
)
output:
INSERT INTO test (x) OUTPUT
inserted.id VALUES (CAST(%(x)s AS
VARBINARY(max))