]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
- requires_connection() -> is_offline_mode()
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 16 Nov 2011 22:15:38 +0000 (17:15 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 16 Nov 2011 22:15:38 +0000 (17:15 -0500)
- move "offline" tranasctional markers to env.py script
- move online/offline sections into separate functions in env.py scripts
- move context initial logging to the __init__ method

alembic/context.py
alembic/templates/generic/env.py
alembic/templates/multidb/env.py
alembic/templates/pylons/env.py
tests/test_sql_script.py

index 4bc6b03225b14e4079aa573165edc1d95c8a38c2..20491f390362beb66928e0dca93e8552636aacc6 100644 (file)
@@ -47,6 +47,12 @@ class Context(object):
                             transactional_ddl,
                             self.output_buffer
                             )
+        log.info("Context impl %s.", self.impl.__class__.__name__)
+        if self.as_sql:
+            log.info("Generating static SQL")
+        log.info("Will assume %s DDL.", 
+                        "transactional" if self.impl.transactional_ddl 
+                        else "non-transactional")
 
     def _current_rev(self):
         if self.as_sql:
@@ -74,15 +80,6 @@ class Context(object):
                     )
 
     def run_migrations(self, **kw):
-        log.info("Context impl %s.", self.impl.__class__.__name__)
-        if self.as_sql:
-            log.info("Generating static SQL")
-        log.info("Will assume %s DDL.", 
-                        "transactional" if self.impl.transactional_ddl 
-                        else "non-transactional")
-
-        if self.as_sql and self.impl.transactional_ddl:
-            self.impl.static_output("BEGIN;")
 
         current_rev = rev = False
         for change, prev_rev, rev in self._migrations_fn(
@@ -106,9 +103,6 @@ class Context(object):
             if self.as_sql and not rev:
                 _version.drop(self.connection)
 
-        if self.as_sql and self.impl.transactional_ddl:
-            self.impl.static_output("COMMIT;")
-
     def execute(self, sql):
         self.impl._exec(sql)
 
@@ -171,18 +165,35 @@ def _clear():
     _context = _script = None
     _context_opts = {}
 
-def requires_connection():
-    """Return True if the current migrations environment should have
-    an active database connection.
+def is_offline_mode():
+    """Return True if the current migrations environment 
+    is running in "offline mode".
     
-    Currently, this is ``True`` or ``False`` depending 
+    This is ``True`` or ``False`` depending 
     on the the ``--sql`` flag passed.
 
     This function does not require that the :class:`.Context` 
     has been configured.
     
     """
-    return not _context_opts.get('as_sql', False)
+    return _context_opts.get('as_sql', False)
+
+def is_transactional_ddl():
+    """Return True if the context is configured to expect a
+    transactional DDL capable backend.
+    
+    This defaults to the type of database in use, and 
+    can be overridden by the ``transactional_ddl`` argument
+    to :func:`.configure`
+    
+    This function requires that a :class:`.Context` has first been 
+    made available via :func:`.configure`.
+    
+    """
+    return get_context().impl.transactional_ddl
+
+def requires_connection():
+    return not is_offline_mode()
 
 def get_head_revision():
     """Return the hex identifier of the 'head' revision.
@@ -373,5 +384,18 @@ def get_context():
         raise Exception("No context has been configured yet.")
     return _context
 
+def get_bind():
+    """Return the current 'bind'.
+    
+    In "online" mode, this is the 
+    :class:`sqlalchemy.engine.Connection` currently being used
+    to emit SQL to the database.
+
+    This function requires that a :class:`.Context` has first been 
+    made available via :func:`.configure`.
+    
+    """
+    return get_context().bind
+
 def get_impl():
     return get_context().impl
\ No newline at end of file
index 8f5018f1295e7c3339fd4827a45a1bb023baddfc..423c53e6458b34baed62b44ae2f554275da322c0 100644 (file)
@@ -10,26 +10,39 @@ config = context.config
 # This line sets up loggers basically.
 fileConfig(config.config_file_name)
 
-
 # other values from the config, defined by the needs of env.py,
 # can be acquired:
 # my_important_option = config.get_main_option("my_important_option")
 # ... etc.
 
-# if we're running in --sql mode, do everything connectionless.
-# We only need a URL, not an Engine, thereby not even requiring
-# the DBAPI be installed, though an actual Engine would of course be fine as well.
-if not context.requires_connection():
+def run_migrations_offline():
+    """Run migrations in 'offline' mode.
+
+    This configures the context with just a URL
+    and not an Engine, though an Engine is acceptable
+    here as well.  By skipping the Engine creation
+    we don't even need a DBAPI to be available.
+    
+    Calls to context.execute() here emit the given string to the
+    script output.
+    
+    """
     url = config.get_main_option("sqlalchemy.url")
     context.configure(url=url)
+
+    if context.is_transactional_ddl():
+        context.execute("BEGIN")
     context.run_migrations()
+    if context.is_transactional_ddl():
+        context.execute("COMMIT")
 
-# otherwise we need to make a connection.
-else:
+def run_migrations_online():
+    """Run migrations in 'online' mode.
 
-    # Produce a SQLAlchemy engine using the key/values
-    # within the "alembic" section of the documentation,
-    # other otherwise what config_ini_section points to.
+    In this scenario we need to create an Engine
+    and associate a connection with the context.
+    
+    """
     engine = engine_from_config(
                 config.get_section(config.config_ini_section), prefix='sqlalchemy.')
 
@@ -42,4 +55,10 @@ else:
         trans.commit()
     except:
         trans.rollback()
-        raise
\ No newline at end of file
+        raise
+
+if context.is_offline_mode():
+    run_migrations_offline()
+else:
+    run_migrations_online()
+
index e561e9becf945d031d012ab108e0bc106df84bc7..1ffa597c3395f8be87fd4dd8266fb8c4e69163ed 100644 (file)
@@ -12,22 +12,26 @@ logging.fileConfig(options.config_file)
 # databases.
 db_names = options.get_main_option('databases')
 
-# set aside if we need engines or just URLs to do this.
-need_engine = context.requires_connection()
-
-# load up SQLAlchemy engines or URLs.
-engines = {}
-for name in re.split(r',\s*', db_names):
-    engines[name] = rec = {}
-    if need_engine:
-        rec['engine'] = engine_from_config(context.config.get_section(name),
-                                prefix='sqlalchemy.')
-    else:
+def run_migrations_offline():
+    """Run migrations in 'offline' mode.
+
+    This configures the context with just a URL
+    and not an Engine, though an Engine is acceptable
+    here as well.  By skipping the Engine creation
+    we don't even need a DBAPI to be available.
+    
+    Calls to context.execute() here emit the given string to the
+    script output.
+    
+    """
+    # for the --sql use case, run migrations for each URL into
+    # individual files.
+
+    engines = {}
+    for name in re.split(r',\s*', db_names):
+        engines[name] = rec = {}
         rec['url'] = context.config.get_section_option(name, "sqlalchemy.url")
 
-# for the --sql use case, run migrations for each URL into
-# individual files.
-if not need_engine:
     for name, rec in engines.items():
         file_ = "%s.sql" % name
         sys.stderr.write("Writing output to %s\n" % file_)
@@ -37,9 +41,23 @@ if not need_engine:
                 )
         context.run_migrations(engine=name)
 
-# for the direct-to-DB use case, start a transaction on all
-# engines, then run all migrations, then commit all transactions.
-else:
+def run_migrations_online():
+    """Run migrations in 'online' mode.
+
+    In this scenario we need to create an Engine
+    and associate a connection with the context.
+    
+    """
+
+    # for the direct-to-DB use case, start a transaction on all
+    # engines, then run all migrations, then commit all transactions.
+
+    engines = {}
+    for name in re.split(r',\s*', db_names):
+        engines[name] = rec = {}
+        rec['engine'] = engine_from_config(context.config.get_section(name),
+                                    prefix='sqlalchemy.')
+
     for name, rec in engines.items():
         engine = rec['engine']
         rec['connection'] = conn = engine.connect()
@@ -67,4 +85,9 @@ else:
     except:
         for rec in engines.values():
             rec['transaction'].rollback()
-        raise
\ No newline at end of file
+        raise
+
+if context.is_offline_mode():
+    run_migrations_offline()
+else:
+    run_migrations_online()
index 2a3d99726c70bb8fda56c2542f9e3f318784cc4d..2726f906979ea4ee4f95d570d4ed25daf3e90c49 100644 (file)
@@ -23,12 +23,29 @@ except:
 # customize this section for non-standard engine configurations.
 meta = __import__("%s.model.meta" % config['pylons.package']).model.meta
 
+def run_migrations_offline():
+    """Run migrations in 'offline' mode.
 
-if not context.requires_connection():
+    This configures the context with just a URL
+    and not an Engine, though an Engine is acceptable
+    here as well.  By skipping the Engine creation
+    we don't even need a DBAPI to be available.
+    
+    Calls to context.execute() here emit the given string to the
+    script output.
+    
+    """
     context.configure(
                 dialect_name=meta.engine.name)
     context.run_migrations()
-else:
+
+def run_migrations_online():
+    """Run migrations in 'online' mode.
+
+    In this scenario we need to create an Engine
+    and associate a connection with the context.
+    
+    """
     connection = meta.engine.connect()
     context.configure_connection(connection)
     trans = connection.begin()
@@ -37,4 +54,9 @@ else:
         trans.commit()
     except:
         trans.rollback()
-        raise
\ No newline at end of file
+        raise
+
+if context.is_offline_mode():
+    run_migrations_offline()
+else:
+    run_migrations_online()
index 54538a10951035110f64614952ff00033f12bc1f..3e4dc3276a58551e8bf81d7483fcb23bd4f83745 100644 (file)
@@ -55,3 +55,4 @@ def test_stamp():
     with capture_context_buffer() as buf:
         command.stamp(cfg, "head", sql=True)
     assert "UPDATE alembic_version SET version_num='%s';" % c in buf.getvalue()
+