你不必改變SQLAlchemy的來源得到它以不同的編譯東西。編譯Binary
到BINARY
的相關代碼here:
class MySQLCompiler(compiler.SQLCompiler):
...
def visit_typeclause(self, typeclause, type_=None):
if type_ is None:
type_ = typeclause.type.dialect_impl(self.dialect)
if isinstance(type_, sqltypes.TypeDecorator):
return self.visit_typeclause(typeclause, type_.impl)
elif isinstance(type_, sqltypes.Integer):
if getattr(type_, 'unsigned', False):
return 'UNSIGNED INTEGER'
else:
return 'SIGNED INTEGER'
elif isinstance(type_, sqltypes.TIMESTAMP):
return 'DATETIME'
elif isinstance(type_, (sqltypes.DECIMAL, sqltypes.DateTime,
sqltypes.Date, sqltypes.Time)):
return self.dialect.type_compiler.process(type_)
elif isinstance(type_, sqltypes.String) \
and not isinstance(type_, (ENUM, SET)):
adapted = CHAR._adapt_string_for_cast(type_)
return self.dialect.type_compiler.process(adapted)
elif isinstance(type_, sqltypes._Binary):
return 'BINARY' # <-------------------------------- RIGHT HERE
elif isinstance(type_, sqltypes.JSON):
return "JSON"
elif isinstance(type_, sqltypes.NUMERIC):
return self.dialect.type_compiler.process(
type_).replace('NUMERIC', 'DECIMAL')
else:
return None
所以,我們只需要截取的是與我們自己的編譯邏輯:
from sqlalchemy.sql.elements import TypeClause
from sqlalchemy.types import _Binary
from sqlalchemy.ext.compiler import compiles
@compiles(TypeClause, "mysql")
def _compile_typeclause(element, compiler, **kwargs):
if isinstance(element.type, _Binary):
t = "BINARY"
if element.type.length:
t += "({})".format(element.type.length)
return t
return compiler.visit_typeclause(element, **kwargs)
我最初的想法是,任何列聲明爲'二進制( N)'在MySQL中的任何'Binary(n)'時總是與'N'的值在0和255之間相同。例如,MSSQL/SQLAlchemy中的整數列只需要知道max-length知道是否使用tinyint,smallint,int或bigint。在他們各自的範圍內,我認爲價值並不重要。 – sytech
如果我嘗試執行沒有長度參數的查詢二進制類型,我沒有得到任何結果。如果我用二進制類型的長度參數執行它,我得到一行作爲結果。就那麼簡單。 – buhtla