On Wednesday, July 5, 2017 at 12:35:22 PM UTC-7, Mike Bayer wrote: > > On Wed, Jul 5, 2017 at 12:45 PM, kristian kvilekval > <kkvil...@gmail.com <javascript:>> wrote: > > I have some services that automatically try to run all outstanding > > migrations when started using alembic upgrade. > > > > I have noticed an issue when I start multiple services in parallel (a > > typical service deploy), that each one is actually trying to run the > > migration script. > > > > I would really like that one and only one service attempts the upgrade > while > > the others wait for the migration to complete or simply just go ahead. > > > > I would think the right place would be to store some state in the DB > that a > > migration is being attempted and that the parallel scripts would be able > to > > read this before doing their own migration. > > > > Is this right or is there a better way to handle this situation. If > this is > > right then does alembic itself store the state or is their a recipe for > what > > I am asking ? > > Well you need to lock on something. If all your processes are on one > server, use a lockfile. If not, perhaps use something like redis or > memcached to produce a distributed lock, if you have such a service > handy already (might be overkill if not). If you are using MySQL and > can handle running "LOCK TABLES", then perhaps add a "LOCK TABLES / > UNLOCK TABLES" (https://dev.mysql.com/doc/refman/5.7/en/lock-tables.html) > block to your env.py within the transaction, using the alembic_version > table itself as the target that you're locking (assuming it exists, > which you'd have to check first). Postgresql offers LOCK > (https://www.postgresql.org/docs/9.4/static/sql-lock.html), which also > should work but you have to be more careful that the LOCK is scoped to > the transaction started/committed in env.py. > > As far as not using LOCK and instead just using a row of some kind, > you just have to make sure the row truly provides locking behavior; > some form of SELECT FOR SHARE or similar in conjunction with proper > transaction isolation would probably achieve this. > > I would prefer to keep this in alembic and not rely on outside resources that may or may not be available. It is multi hosted with no shared filesystem so I again, I had hoped to use the database to provide the locking behaviour. This does seems like a common case for scalable services.
Locking the migration table seems like the way to go. We are using postgres in production and sqlite for dev so I am wondering if there is a database agnostic way to specify the locks? Thanks, Kris -- 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.