[Sqlalchemy-commits] sqlalchemy: - [feature] Added create_type constructor argument
Brought to you by:
zzzeek
From: <co...@sq...> - 2011-11-29 03:30:28
|
details: http://hg.sqlalchemy.org/sqlalchemy/sqlalchemy/rev/a649e0e9af72 changeset: 7930:a649e0e9af72 user: zzzeek date: Mon Nov 28 22:28:28 2011 -0500 description: - [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. diffstat: CHANGES | 8 ++ doc/build/core/types.rst | 2 +- doc/build/dialects/postgresql.rst | 2 +- lib/sqlalchemy/dialects/postgresql/base.py | 83 +++++++++++++++++++++++++++++- lib/sqlalchemy/types.py | 6 ++ test/dialect/test_postgresql.py | 18 ++++++ 6 files changed, 116 insertions(+), 3 deletions(-) diffs (195 lines): diff -r d310417b77b7 -r a649e0e9af72 CHANGES --- a/CHANGES Mon Nov 28 12:44:56 2011 -0500 +++ b/CHANGES Mon Nov 28 22:28:28 2011 -0500 @@ -138,6 +138,14 @@ "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 -r d310417b77b7 -r a649e0e9af72 doc/build/core/types.rst --- a/doc/build/core/types.rst Mon Nov 28 12:44:56 2011 -0500 +++ b/doc/build/core/types.rst Mon Nov 28 22:28:28 2011 -0500 @@ -58,7 +58,7 @@ .. autoclass:: Enum :show-inheritance: - :members: + :members: __init__, create, drop .. autoclass:: Float :show-inheritance: diff -r d310417b77b7 -r a649e0e9af72 doc/build/dialects/postgresql.rst --- a/doc/build/dialects/postgresql.rst Mon Nov 28 12:44:56 2011 -0500 +++ b/doc/build/dialects/postgresql.rst Mon Nov 28 22:28:28 2011 -0500 @@ -44,7 +44,7 @@ :show-inheritance: .. autoclass:: ENUM - :members: __init__ + :members: __init__, create, drop :show-inheritance: .. autoclass:: INET diff -r d310417b77b7 -r a649e0e9af72 lib/sqlalchemy/dialects/postgresql/base.py --- a/lib/sqlalchemy/dialects/postgresql/base.py Mon Nov 28 12:44:56 2011 -0500 +++ b/lib/sqlalchemy/dialects/postgresql/base.py Mon Nov 28 22:28:28 2011 -0500 @@ -432,8 +432,74 @@ 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 @@ 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 @@ 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 -r d310417b77b7 -r a649e0e9af72 lib/sqlalchemy/types.py --- a/lib/sqlalchemy/types.py Mon Nov 28 12:44:56 2011 -0500 +++ b/lib/sqlalchemy/types.py Mon Nov 28 22:28:28 2011 -0500 @@ -1784,6 +1784,12 @@ 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 -r d310417b77b7 -r a649e0e9af72 test/dialect/test_postgresql.py --- a/test/dialect/test_postgresql.py Mon Nov 28 12:44:56 2011 -0500 +++ b/test/dialect/test_postgresql.py Mon Nov 28 22:28:28 2011 -0500 @@ -451,6 +451,24 @@ 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. |