Thanks Michael for the tip. Here is the code I came up. Please feel free to
make changes and use in your cookbook:


Use Case 1: If someone new come to the project and they use
 db.create_all() or some script to create a fresh new database. There is no
alembic_version table and the person will run into problems when doing the
upgrade. The following code snippet can be added to database (re)create
script to make sure the new database has most up-to-date version.
        # create db tables
        db.create_all()
# add database version table and add current head version
alembic_cfg = Config("alembic.ini")
connection = db.engine.connect()
context = MigrationContext.configure(connection)
context._ensure_version_table()
script = ScriptDirectory.from_config(alembic_cfg)
head_revision = script.get_current_head()
context.stamp(script, head_revision)

Use Case 2: When doing tests, you may want to test your database migration
script as well. Here is the code snippet:
        # in your tests
        def test_migration(self):
                # create database
                db.create_all()
# create config object
alembic_cfg = Config("alembic.ini")
# get connection from db object
connection = db.engine.connect()
alembic_cfg.connection = connection
# make sure version table exists or create one
context = MigrationContext.configure(connection)
context._ensure_version_table()
# insert/update the head version
script = ScriptDirectory.from_config(alembic_cfg)
head_revision = script.get_current_head()
context.stamp(script, head_revision)

command.downgrade(alembic_cfg, "base")

command.upgrade(alembic_cfg, "head")

        # in your alembic/env.py
    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.

"""
# the connection may come from the config object
if hasattr(config, 'connection'):
# load connection from config object
connection = config.connection
else:
# load connection from config file
engine = engine_from_config(
config.get_section(config.config_ini_section),
prefix='sqlalchemy.',
poolclass=pool.NullPool
)
connection = engine.connect()

context.configure(
connection=connection,
target_metadata=target_metadata
)

try:
with context.begin_transaction():
context.run_migrations()
finally:
# don't close connection if it is from outside
if not hasattr(config, 'connection'):
connection.close()


Hope it helps.


Cheers,
Pan

On Fri, Dec 26, 2014 at 6:21 PM, Michael Bayer <mike...@zzzcomputing.com>
wrote:

> just tack it on the Config object for now, I’ll have to add more support
> for this kind of feature.
>
>
>
> Pan Luo <luopa...@gmail.com> wrote:
>
> Looks like alembic_cfg only accepts string options. (set_main_option()).
> Is there a way to pass connect object? Thanks.
>
>
> Cheers,
> Pan
>
> On Wed, Dec 24, 2014 at 8:35 AM, Michael Bayer <mike...@zzzcomputing.com>
> wrote:
>
>> Pan Luo <luopa...@gmail.com> wrote:
>>
>> If someone new come to the project and they use  db.create_all() or some
>> script to create a fresh new database with declared models. There is no
>> alembic_version table and he/she will run into problems when doing the
>> upgrade. Is there something in alembic to support it? I have been poking
>> around and came up with the following:
>>
>>  alembic_cfg = Config("alembic.ini")
>>  context = MigrationContext.configure(db.engine.connect())
>>  current_rev = context.get_current_revision()
>>  context._ensure_version_table()
>>
>>  script = ScriptDirectory.from_config(alembic_cfg)
>>  head_revision = script.get_current_head()
>>  context.stamp(script, head_revision)
>>
>>  command.downgrade(alembic_cfg, "base")
>>
>> However, it works with file based sqlite db but no in memory one:
>> Error: Destination base is not a valid downgrade target from current head(s)
>>
>> It seems the migrationcontext use different from the one I generated and
>> the one used in the alembic, so the current revision was empty when I do
>> the downgrade (just for. Not sure why file based sqlite works.
>>
>>
>> A SQLite :memory: database only exists with the span of a single SQLite
>> database connection.   You get that above when you call
>> db.engine.connect().   But then when you call command.downgrade(), you are
>> not passing this connection to that command in any way; the connection is
>> stuck inside your MigrationContext which isn’t present in
>> command.downgrade(alembic_cfg).   command.downgrade() then calls upon your
>> env.py in order to get the database connection, and you probably have
>> another engine.connect() in there using a different engine (and therefore
>> connection pool).  This makes a brand new :memory: connection that has no
>> state on it.
>>
>> So you’d want to send an argument into the alembic_cfg in this case which
>> refers to that connection from db.engine.connect(), which your env.py can
>> pull out and make use of instead of connecting in some other way.  This
>> requires modifications to your env.py to look for this connection and use
>> it, instead of connecting again. Or you can set up this connection as a
>> global variable somewhere.
>>
>> This is a common issue so at some point I will add recipes to the
>> documentation that show how to transfer a connection from the outside of
>> command.xyz(), through the env.py and into the migration context.
>>
>>
>>
>> --
>> You received this message because you are subscribed to a topic in the
>> Google Groups "sqlalchemy-alembic" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/sqlalchemy-alembic/1EMiDnOlQjI/unsubscribe
>> .
>> To unsubscribe from this group and all its topics, send an email to
>> sqlalchemy-alembic+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy-alembic" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sqlalchemy-alembic+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
>  --
> You received this message because you are subscribed to a topic in the
> Google Groups "sqlalchemy-alembic" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/sqlalchemy-alembic/1EMiDnOlQjI/unsubscribe
> .
> To unsubscribe from this group and all its topics, send an email to
> sqlalchemy-alembic+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy-alembic" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy-alembic+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to