@compiles recipe interferes with compile for ARRAY on totally different dialect

Issue #3732 resolved
Mike Bayer repo owner created an issue

1.1 regression:

from sqlalchemy import MetaData
from sqlalchemy import Column, Table
from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy import String
from sqlalchemy.ext.compiler import compiles


@compiles(ARRAY, "sqlite")
def compile_binary_sqlite(type_, compiler, **kw):
    return "STRING"

metadata = MetaData()
t = Table('test', metadata, Column('x', ARRAY(String)))

from sqlalchemy.dialects import postgresql
from sqlalchemy.schema import CreateTable
print CreateTable(t).compile(dialect=postgresql.dialect())

succeeds in 1.0. 1.1:

#!

sqlalchemy.exc.CompileError: (in table 'test', column 'x'): <class 'sqlalchemy.dialects.postgresql.array.ARRAY'> construct has no default compilation handler.

Comments (2)

  1. Mike Bayer reporter

    OK this is not really a new thing in the abstract, only because PG ARRAY now subclasses sqltypes.ARRAY. It doesn't have __visit_name__ in __class__.__dict__, so the compiles extension assumes it's a subclassed construct that doesn't have a user-defined compilation scheme. How to differentiate between an end-user subclass of an object that has a visitation scheme? I think just fall back to the base approach...

  2. Mike Bayer reporter

    Ensure @compiles calls down to the original compilation scheme

    Made a slight behavioral change in the sqlalchemy.ext.compiler extension, whereby the existing compilation schemes for an established construct would be removed if that construct was itself didn't already have its own dedicated __visit_name__. This was a rare occurrence in 1.0, however in 1.1 :class:.postgresql.ARRAY subclasses :class:.sqltypes.ARRAY and has this behavior. As a result, setting up a compilation handler for another dialect such as SQLite would render the main :class:.postgresql.ARRAY object no longer compilable.

    Fixes: #3732 Change-Id: If2c1ada4eeb09157885888e41f529173902f2b49

    → <<cset acd8b1c107d5>>

  3. Log in to comment