summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2011-11-28 22:28:28 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2011-11-28 22:28:28 -0500
commitb854074c6dd93cfeb4c5335a4469c700c4d47f04 (patch)
tree195a330efb22180b60656146bd18ed895007b378
parentbeef2b5aa811efd42a111c87a4308d6584c78b97 (diff)
downloadsqlalchemy-b854074c6dd93cfeb4c5335a4469c700c4d47f04.tar.gz
- [feature] Added create_type constructor argument
to pg.ENUM. When False, no CREATE/DROP or checking for the type will be performed as part of a table create/drop event; only the create()/drop)() methods called directly will do this. Helps with Alembic "offline" scripts.
-rw-r--r--CHANGES8
-rw-r--r--doc/build/core/types.rst2
-rw-r--r--doc/build/dialects/postgresql.rst2
-rw-r--r--lib/sqlalchemy/dialects/postgresql/base.py83
-rw-r--r--lib/sqlalchemy/types.py6
-rw-r--r--test/dialect/test_postgresql.py18
6 files changed, 116 insertions, 3 deletions
diff --git a/CHANGES b/CHANGES
index f3793cfc3..04e45d97d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -138,6 +138,14 @@ CHANGES
"checkfirst" turned on it only needs to
check for the ENUM once. [ticket:2311]
+ - [feature] Added create_type constructor argument
+ to pg.ENUM. When False, no CREATE/DROP or
+ checking for the type will be performed as part
+ of a table create/drop event; only the
+ create()/drop)() methods called directly
+ will do this. Helps with Alembic "offline"
+ scripts.
+
- mysql
- [bug] Unicode adjustments allow latest pymysql
(post 0.4) to pass 100% on Python 2.
diff --git a/doc/build/core/types.rst b/doc/build/core/types.rst
index 4e55b25d7..b7b4e3488 100644
--- a/doc/build/core/types.rst
+++ b/doc/build/core/types.rst
@@ -58,7 +58,7 @@ Standard Types`_ and the other sections of this chapter.
.. autoclass:: Enum
:show-inheritance:
- :members:
+ :members: __init__, create, drop
.. autoclass:: Float
:show-inheritance:
diff --git a/doc/build/dialects/postgresql.rst b/doc/build/dialects/postgresql.rst
index 6e45992eb..b34c07684 100644
--- a/doc/build/dialects/postgresql.rst
+++ b/doc/build/dialects/postgresql.rst
@@ -44,7 +44,7 @@ construction arguments, are as follows:
:show-inheritance:
.. autoclass:: ENUM
- :members: __init__
+ :members: __init__, create, drop
:show-inheritance:
.. autoclass:: INET
diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py
index e3beeab79..673b86add 100644
--- a/lib/sqlalchemy/dialects/postgresql/base.py
+++ b/lib/sqlalchemy/dialects/postgresql/base.py
@@ -432,8 +432,74 @@ class ARRAY(sqltypes.MutableType, sqltypes.Concatenable, sqltypes.TypeEngine):
PGArray = ARRAY
class ENUM(sqltypes.Enum):
+ """Postgresql ENUM type.
+
+ This is a subclass of :class:`.types.Enum` which includes
+ support for PG's ``CREATE TYPE``.
+
+ :class:`~.postgresql.ENUM` is used automatically when
+ using the :class:`.types.Enum` type on PG assuming
+ the ``native_enum`` is left as ``True``. However, the
+ :class:`~.postgresql.ENUM` class can also be instantiated
+ directly in order to access some additional Postgresql-specific
+ options, namely finer control over whether or not
+ ``CREATE TYPE`` should be emitted.
+
+ Note that both :class:`.types.Enum` as well as
+ :class:`~.postgresql.ENUM` feature create/drop
+ methods; the base :class:`.types.Enum` type ultimately
+ delegates to the :meth:`~.postgresql.ENUM.create` and
+ :meth:`~.postgresql.ENUM.drop` methods present here.
+
+ """
+
+ def __init__(self, *enums, **kw):
+ """Construct an :class:`~.postgresql.ENUM`.
+
+ Arguments are the same as that of
+ :class:`.types.Enum`, but also including
+ the following parameters.
+
+ :param create_type: Defaults to True.
+ Indicates that ``CREATE TYPE`` should be
+ emitted, after optionally checking for the
+ presence of the type, when the parent
+ table is being created; and additionally
+ that ``DROP TYPE`` is called when the table
+ is dropped. When ``False``, no check
+ will be performed and no ``CREATE TYPE``
+ or ``DROP TYPE`` is emitted, unless
+ :meth:`~.postgresql.ENUM.create`
+ or :meth:`~.postgresql.ENUM.drop`
+ are called directly.
+ Setting to ``False`` is helpful
+ when invoking a creation scheme to a SQL file
+ without access to the actual database -
+ the :meth:`~.postgresql.ENUM.create` and
+ :meth:`~.postgresql.ENUM.drop` methods can
+ be used to emit SQL to a target bind.
+ (new in 0.7.4)
+
+ """
+ self.create_type = kw.pop("create_type", True)
+ super(ENUM, self).__init__(*enums, **kw)
def create(self, bind=None, checkfirst=True):
+ """Emit ``CREATE TYPE`` for this
+ :class:`~.postgresql.ENUM`.
+
+ If the underlying dialect does not support
+ Postgresql CREATE TYPE, no action is taken.
+
+ :param bind: a connectable :class:`.Engine`,
+ :class:`.Connection`, or similar object to emit
+ SQL.
+ :param checkfirst: if ``True``, a query against
+ the PG catalog will be first performed to see
+ if the type does not exist already before
+ creating.
+
+ """
if not bind.dialect.supports_native_enum:
return
@@ -442,6 +508,20 @@ class ENUM(sqltypes.Enum):
bind.execute(CreateEnumType(self))
def drop(self, bind=None, checkfirst=True):
+ """Emit ``DROP TYPE`` for this
+ :class:`~.postgresql.ENUM`.
+
+ If the underlying dialect does not support
+ Postgresql DROP TYPE, no action is taken.
+
+ :param bind: a connectable :class:`.Engine`,
+ :class:`.Connection`, or similar object to emit
+ SQL.
+ :param checkfirst: if ``True``, a query against
+ the PG catalog will be first performed to see
+ if the type actually exists before dropping.
+
+ """
if not bind.dialect.supports_native_enum:
return
@@ -458,7 +538,8 @@ class ENUM(sqltypes.Enum):
sequence without relying upon "checkfirst".
"""
-
+ if not self.create_type:
+ return True
if '_ddl_runner' in kw:
ddl_runner = kw['_ddl_runner']
if '_pg_enums' in ddl_runner.memo:
diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py
index 79799da8f..136de147e 100644
--- a/lib/sqlalchemy/types.py
+++ b/lib/sqlalchemy/types.py
@@ -1784,6 +1784,12 @@ class Enum(String, SchemaType):
By default, uses the backend's native ENUM type if available,
else uses VARCHAR + a CHECK constraint.
+
+ See also:
+
+ :class:`~.postgresql.ENUM` - PostgreSQL-specific type,
+ which has additional functionality.
+
"""
__visit_name__ = 'enum'
diff --git a/test/dialect/test_postgresql.py b/test/dialect/test_postgresql.py
index b4b7e818c..7279508ba 100644
--- a/test/dialect/test_postgresql.py
+++ b/test/dialect/test_postgresql.py
@@ -451,6 +451,24 @@ class EnumTest(fixtures.TestBase, AssertsExecutionResults, AssertsCompiledSQL):
metadata.drop_all(testing.db)
@testing.provide_metadata
+ def test_disable_create(self):
+ metadata = self.metadata
+
+ e1 = postgresql.ENUM('one', 'two', 'three',
+ name="myenum",
+ create_type=False)
+
+ t1 = Table('e1', metadata,
+ Column('c1', e1)
+ )
+ # table can be created separately
+ # without conflict
+ e1.create(bind=testing.db)
+ t1.create(testing.db)
+ t1.drop(testing.db)
+ e1.drop(bind=testing.db)
+
+ @testing.provide_metadata
def test_generate_multiple(self):
"""Test that the same enum twice only generates once
for the create_all() call, without using checkfirst.