Pan Luo <luopa...@gmail.com> wrote:

> 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)


you shouldn’t be calling _ensure_version_table().  You should be calling 
command.stamp() which will run the full migration environment and ensure the 
version table is present.    The recipe at 
http://alembic.readthedocs.org/en/latest/cookbook.html#building-an-up-to-date-database-from-scratch
 should be doing what this is trying to do, and if it doesn’t work right now, 
that’s a bug.   Additionally, there is no need for “get_current_head()”, 
command.stamp() can be called with the string “head” directly.


> 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)

same here.  the only difference here is that you want to send through a SQLite 
:memory: database, so you can attach that to alembic_cfg and have it invoked 
inside of your env.py as the source of connectivity.



> 
>               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 
> <mailto: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 <mailto: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 
>> <mailto:mike...@zzzcomputing.com>> wrote:
>> Pan Luo <luopa...@gmail.com <mailto: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 
>> <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 
>> <mailto:sqlalchemy-alembic+unsubscr...@googlegroups.com>.
>> For more options, visit https://groups.google.com/d/optout 
>> <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 
>> <mailto:sqlalchemy-alembic+unsubscr...@googlegroups.com>.
>> For more options, visit https://groups.google.com/d/optout 
>> <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 
> <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 
> <mailto:sqlalchemy-alembic+unsubscr...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout 
> <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 
> <mailto:sqlalchemy-alembic+unsubscr...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout 
> <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