Reputation: 33
I'm querying an SQL Server database using SQLAlchemy and need to cast a column to varbinary(max). The thing I am struggling with is the "max" part. I can get the cast to work for any actual number (say varbinary(20)), but I cannot find how to get it to work for the "max" size of the varbinary column.
Any pointers? Links? Solutions?
Regards, Mark
Upvotes: 3
Views: 5343
Reputation: 974
The sqlalchemy team resolved this issue based on this thread (Power of community!). You can find it here Large Text/Binary Type Deprecation
To use VARBINARY(max) use LargetBinary as datatype, and set the flag deprecate_large_types=True
From the site; create an engine with the flag deprecate_large_types=True:
eng = create_engine("mssql+pymssql://user:pass@host/db",deprecate_large_types=True)
When this flag is True, the UnicodeText, Text and LargeBinary datatypes, when used to render DDL, will render the types NVARCHAR(max), VARCHAR(max), and VARBINARY(max), respectively. This is a new behavior as of the addition of this flag.
Upvotes: 0
Reputation: 75317
I hope you've all noticed we have virtually this exact recipe in the main documentation for custom compilation, without any monkeypatching, here:
@compiles(String, 'mssql')
@compiles(VARCHAR, 'mssql')
def compile_varchar(element, compiler, **kw):
if element.length == 'max':
return "VARCHAR('max')"
else:
return compiler.visit_VARCHAR(element, **kw)
foo = Table('foo', metadata,
Column('data', VARCHAR('max'))
)
Upvotes: 5
Reputation: 77082
SQLAlchemy does not support this out of the box (create a feature request on sqlalchemy trac).
In order to make it work for you, hack it: add the following method to the MSTypeCompiler
class in sqlalchemy\dialects\mssql\base.py
:
def visit_VARBINARY(self, type_):
if type_.length == 'MAX':
return "VARBINARY(MAX)"
else:
return "VARBINARY(%d)" % type_.length
and then use the query with the MSVarBinary
type:
from sqlalchemy.dialects.mssql.base import MSVarBinary
...
q = ... cast(mytable.c.mycolumn, MSVarBinary('MAX')) ...
Upvotes: 2