From 133ff1d16baae56147ecf5f37a7eabbceb8870d7 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 8 Nov 2014 18:59:28 -0500 Subject: [PATCH] - start docs - run tests against mysql/PG to make sure auto mode works at least, try a proof of concept recreate for MySQL. recreate doesn't work on PG as constraint names are global (ugh). Will have to figure something out on that. --- docs/build/tutorial.rst | 33 +++++++++++++++++++++++++++++++++ tests/test_batch.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/docs/build/tutorial.rst b/docs/build/tutorial.rst index 012bcc5d..652a7197 100644 --- a/docs/build/tutorial.rst +++ b/docs/build/tutorial.rst @@ -910,6 +910,39 @@ this within the ``run_migrations_offline()`` function:: else: run_migrations_online() +.. _batch: + +Running SQLite "Batch" Migrations +================================= + +The SQLite database presents an inconvenient challenge to migration tools, +in that it has almost no support for the ALTER statement upon which +relational schema migrations rely upon. The rationale for this stems from +philosophical and architecural concerns within SQLite, and they are unlikely +to be changed. + +Migration tools are instead expected to produce copies of SQLite tables that +correspond to the new structure, to transfer the data from the existing +table to the new one, then drop the old table. In order to accommodate this +workflow in a way that is reasonably predictable, while remaining compatible +with other databases, Alembic provides the "batch" operations context. +This context provides the table recreate plus data copy operation for SQLite, +and can also be instructed to use this flow for other databases as well, +providing an alternative scheme in some cases where the blocking behavior of +some ALTER statements is to be avoided. + +Within this context, a relational table is named, and then a series of +any number of mutation operations to that table then proceed within the +block. When the context is complete, the above mentioned table-recreate +and data copy operation proceeds, but *only* if appropriate for the target +database; for other databases, the batch context proceeds using traditional +ALTER statements, unless the context is set to "always". + +TODO: "recreate" doesn't work very well for Postgresql due to constraint naming +TODO: caveats, beta status + + + .. _tutorial_constraint_names: The Importance of Naming Constraints diff --git a/tests/test_batch.py b/tests/test_batch.py index 4f2695b0..2d9bb512 100644 --- a/tests/test_batch.py +++ b/tests/test_batch.py @@ -1,6 +1,7 @@ from contextlib import contextmanager import re +from alembic.testing import exclusions from alembic.testing import TestBase, eq_, config from alembic.testing.fixtures import op_fixture from alembic.testing import mock @@ -470,3 +471,31 @@ class BatchRoundTripTest(TestBase): {"id": 4, "data": "9.46", "x": 8, 'data2': 'hi'}, {"id": 5, "data": "d5", "x": 9, 'data2': 'hi'} ]) + + +class BatchRoundTripMySQLTest(BatchRoundTripTest): + __only_on__ = "mysql" + + @exclusions.fails() + def test_rename_column_pk(self): + super(BatchRoundTripMySQLTest, self).test_rename_column_pk() + + @exclusions.fails() + def test_rename_column(self): + super(BatchRoundTripMySQLTest, self).test_rename_column() + + @exclusions.fails() + def test_change_type(self): + super(BatchRoundTripMySQLTest, self).test_change_type() + + +class BatchRoundTripPostgresqlTest(BatchRoundTripTest): + __only_on__ = "postgresql" + + @exclusions.fails() + def test_change_type(self): + super(BatchRoundTripPostgresqlTest, self).test_change_type() + + @exclusions.fails() + def test_add_column_recreate(self): + super(BatchRoundTripPostgresqlTest, self).test_add_column_recreate() -- 2.47.2