encouraged to use those functions whenever they correspond
to their needs instead of implementing custom ones.
+ - SchemaType and subclasses Boolean, Enum are now serializable,
+ including their ddl listener and other event callables.
+ [ticket:1694] [ticket:1698]
+
- Added math negation operator support, -x.
- FunctionElement subclasses are now directly executable the
Can be included in the definition of a Table or Column.
"""
- def __init__(self, sqltext, name=None, deferrable=None, initially=None, table=None, _create_rule=None):
+ def __init__(self, sqltext, name=None, deferrable=None,
+ initially=None, table=None, _create_rule=None):
"""Construct a CHECK constraint.
sqltext
self.on = on
self.bind = bind
+ def _create_rule_disable(self, compiler):
+ """Allow disable of _create_rule using a callable.
+
+ Pass to _create_rule using
+ util.portable_instancemethod(self._create_rule_disable)
+ to retain serializability.
+
+ """
+ return False
+
class CreateTable(_CreateDropBase):
"""Represent a CREATE TABLE statement."""
def __init__(self, element, *args, **kw):
super(AddConstraint, self).__init__(element, *args, **kw)
- element._create_rule = lambda compiler: False
+ element._create_rule = util.portable_instancemethod(self._create_rule_disable)
class DropConstraint(_CreateDropBase):
"""Represent an ALTER TABLE DROP CONSTRAINT statement."""
def __init__(self, element, cascade=False, **kw):
self.cascade = cascade
super(DropConstraint, self).__init__(element, **kw)
- element._create_rule = lambda compiler: False
+ element._create_rule = util.portable_instancemethod(self._create_rule_disable)
def _bind_or_error(schemaitem, msg=None):
bind = schemaitem.bind
self.schema = kw.pop('schema', None)
self.metadata = kw.pop('metadata', None)
if self.metadata:
- self.metadata.append_ddl_listener('before-create',
- self._on_metadata_create)
- self.metadata.append_ddl_listener('after-drop',
- self._on_metadata_drop)
+ self.metadata.append_ddl_listener(
+ 'before-create',
+ util.portable_instancemethod(self._on_metadata_create)
+ )
+ self.metadata.append_ddl_listener(
+ 'after-drop',
+ util.portable_instancemethod(self._on_metadata_drop)
+ )
def _set_parent(self, column):
- column._on_table_attach(self._set_table)
+ column._on_table_attach(util.portable_instancemethod(self._set_table))
def _set_table(self, table, column):
- table.append_ddl_listener('before-create', self._on_table_create)
- table.append_ddl_listener('after-drop', self._on_table_drop)
+ table.append_ddl_listener(
+ 'before-create',
+ util.portable_instancemethod(self._on_table_create)
+ )
+ table.append_ddl_listener(
+ 'after-drop',
+ util.portable_instancemethod(self._on_table_drop)
+ )
if self.metadata is None:
- table.metadata.append_ddl_listener('before-create',
- self._on_metadata_create)
- table.metadata.append_ddl_listener('after-drop',
- self._on_metadata_drop)
+ table.metadata.append_ddl_listener(
+ 'before-create',
+ util.portable_instancemethod(self._on_metadata_create)
+ )
+ table.metadata.append_ddl_listener(
+ 'after-drop',
+ util.portable_instancemethod(self._on_metadata_drop)
+ )
@property
def bind(self):
assert_unicode=assert_unicode
)
SchemaType.__init__(self, **kw)
+
+ def _should_create_constraint(self, compiler):
+ return not self.native_enum or \
+ not compiler.dialect.supports_native_enum
def _set_table(self, table, column):
if self.native_enum:
SchemaType._set_table(self, table, column)
- def should_create_constraint(compiler):
- return not self.native_enum or \
- not compiler.dialect.supports_native_enum
e = schema.CheckConstraint(
column.in_(self.enums),
name=self.name,
- _create_rule=should_create_constraint
+ _create_rule=util.portable_instancemethod(self._should_create_constraint)
)
table.append_constraint(e)
"""
self.create_constraint = create_constraint
self.name = name
+
+ def _should_create_constraint(self, compiler):
+ return not compiler.dialect.supports_native_boolean
def _set_table(self, table, column):
if not self.create_constraint:
return
- def should_create_constraint(compiler):
- return not compiler.dialect.supports_native_boolean
-
e = schema.CheckConstraint(
column.in_([0, 1]),
name=self.name,
- _create_rule=should_create_constraint
+ _create_rule=util.portable_instancemethod(self._should_create_constraint)
)
table.append_constraint(e)
else:
return func_or_cls
+class portable_instancemethod(object):
+ """Turn an instancemethod into a (parent, name) pair
+ to produce a serializable callable.
+
+ """
+ def __init__(self, meth):
+ self.target = meth.im_self
+ self.name = meth.__name__
+
+ def __call__(self, *arg, **kw):
+ return getattr(self.target, self.name)(*arg, **kw)
+
def class_hierarchy(cls):
"""Return an unordered sequence of all classes related to cls.
Column('b', Integer)
)
- constraint = CheckConstraint('a < b',name="my_test_constraint", deferrable=True,initially='DEFERRED', table=t)
+ constraint = CheckConstraint('a < b',name="my_test_constraint",
+ deferrable=True,initially='DEFERRED', table=t)
+
+
+ # before we create an AddConstraint,
+ # the CONSTRAINT comes out inline
+ self.assert_compile(
+ schema.CreateTable(t),
+ "CREATE TABLE tbl ("
+ "a INTEGER, "
+ "b INTEGER, "
+ "CONSTRAINT my_test_constraint CHECK (a < b) DEFERRABLE INITIALLY DEFERRED"
+ ")"
+ )
+
self.assert_compile(
schema.AddConstraint(constraint),
- "ALTER TABLE tbl ADD CONSTRAINT my_test_constraint CHECK (a < b) DEFERRABLE INITIALLY DEFERRED"
+ "ALTER TABLE tbl ADD CONSTRAINT my_test_constraint "
+ "CHECK (a < b) DEFERRABLE INITIALLY DEFERRED"
+ )
+
+ # once we make an AddConstraint,
+ # inline compilation of the CONSTRAINT
+ # is disabled
+ self.assert_compile(
+ schema.CreateTable(t),
+ "CREATE TABLE tbl ("
+ "a INTEGER, "
+ "b INTEGER"
+ ")"
)
self.assert_compile(
from sqlalchemy.databases import *
from sqlalchemy.test.schema import Table, Column
from sqlalchemy.test import *
+from sqlalchemy.test.util import picklers
class AdaptTest(TestBase):
(PickleType(), PickleType(), True),
]:
eq_(t1._compare_type_affinity(t2), comp, "%s %s" % (t1, t2))
-
-
+
+class PickleMetadataTest(TestBase):
+ def testmeta(self):
+ for loads, dumps in picklers():
+ column_types = [
+ Column('Boo', Boolean()),
+ Column('Str', String()),
+ Column('Tex', Text()),
+ Column('Uni', Unicode()),
+ Column('Int', Integer()),
+ Column('Sma', SmallInteger()),
+ Column('Big', BigInteger()),
+ Column('Num', Numeric()),
+ Column('Flo', Float()),
+ Column('Dat', DateTime()),
+ Column('Dat', Date()),
+ Column('Tim', Time()),
+ Column('Lar', LargeBinary()),
+ Column('Pic', PickleType()),
+ Column('Int', Interval()),
+ Column('Enu', Enum('x','y','z', name="somename")),
+ ]
+ for column_type in column_types:
+ #print column_type
+ meta = MetaData()
+ Table('foo', meta, column_type)
+ ct = loads(dumps(column_type))
+ mt = loads(dumps(meta))
+
+
class UserDefinedTest(TestBase):
"""tests user-defined types."""