summaryrefslogtreecommitdiff
path: root/tests/test_batch.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2021-08-07 11:48:19 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2021-08-10 12:23:13 -0400
commit3110acba13c22c7d8a934c30dca650b1537a50e3 (patch)
tree78811937b9524be873cfa8e1b5333cce7247eeb0 /tests/test_batch.py
parent8917b3532da6dabc07187adf597573624b32fe3c (diff)
downloadalembic-3110acba13c22c7d8a934c30dca650b1537a50e3.tar.gz
qualify sqlite batch add column for dynamic defaults
Batch "auto" mode will now select for "recreate" if the ``add_column()`` operation is used on SQLite, and the column itself meets the criteria for SQLite where ADD COLUMN is not allowed, in this case a functional or parenthesized SQL expression or a ``Computed`` (i.e. generated) column. Change-Id: Ie948b4b8ad8dc698b458403831e47bac4ad45b8a Fixes: #883
Diffstat (limited to 'tests/test_batch.py')
-rw-r--r--tests/test_batch.py80
1 files changed, 80 insertions, 0 deletions
diff --git a/tests/test_batch.py b/tests/test_batch.py
index 9e0491d..91baef7 100644
--- a/tests/test_batch.py
+++ b/tests/test_batch.py
@@ -26,6 +26,7 @@ from sqlalchemy.schema import CreateTable
from sqlalchemy.sql import column
from sqlalchemy.sql import text
+from alembic import testing
from alembic.ddl import sqlite
from alembic.operations import Operations
from alembic.operations.batch import ApplyBatchImpl
@@ -40,8 +41,16 @@ from alembic.testing import TestBase
from alembic.testing.fixtures import op_fixture
from alembic.util import exc as alembic_exc
from alembic.util.sqla_compat import _select
+from alembic.util.sqla_compat import has_computed
+from alembic.util.sqla_compat import has_identity
from alembic.util.sqla_compat import sqla_14
+if has_computed:
+ from alembic.util.sqla_compat import Computed
+
+if has_identity:
+ from alembic.util.sqla_compat import Identity
+
class BatchApplyTest(TestBase):
def setUp(self):
@@ -1931,6 +1940,77 @@ class BatchRoundTripTest(TestBase):
["id", "data", "x", "data2"],
)
+ def test_add_column_auto_server_default_calculated(self):
+ """test #883"""
+ with self.op.batch_alter_table("foo") as batch_op:
+ batch_op.add_column(
+ Column(
+ "data2",
+ DateTime(),
+ server_default=self._datetime_server_default_fixture(),
+ )
+ )
+
+ self._assert_data(
+ [
+ {"id": 1, "data": "d1", "x": 5, "data2": mock.ANY},
+ {"id": 2, "data": "22", "x": 6, "data2": mock.ANY},
+ {"id": 3, "data": "8.5", "x": 7, "data2": mock.ANY},
+ {"id": 4, "data": "9.46", "x": 8, "data2": mock.ANY},
+ {"id": 5, "data": "d5", "x": 9, "data2": mock.ANY},
+ ]
+ )
+ eq_(
+ [col["name"] for col in inspect(config.db).get_columns("foo")],
+ ["id", "data", "x", "data2"],
+ )
+
+ @testing.combinations((True,), (False,))
+ @testing.exclusions.only_on("sqlite")
+ def test_add_column_auto_generated(self, persisted):
+ """test #883"""
+ with self.op.batch_alter_table("foo") as batch_op:
+ batch_op.add_column(
+ Column(
+ "data2", Integer, Computed("1 + 1", persisted=persisted)
+ )
+ )
+
+ self._assert_data(
+ [
+ {"id": 1, "data": "d1", "x": 5, "data2": 2},
+ {"id": 2, "data": "22", "x": 6, "data2": 2},
+ {"id": 3, "data": "8.5", "x": 7, "data2": 2},
+ {"id": 4, "data": "9.46", "x": 8, "data2": 2},
+ {"id": 5, "data": "d5", "x": 9, "data2": 2},
+ ]
+ )
+ eq_(
+ [col["name"] for col in inspect(config.db).get_columns("foo")],
+ ["id", "data", "x", "data2"],
+ )
+
+ @config.requirements.identity_columns
+ def test_add_column_auto_identity(self):
+ """test #883"""
+
+ self._no_pk_fixture()
+
+ with self.op.batch_alter_table("nopk") as batch_op:
+ batch_op.add_column(Column("id", Integer, Identity()))
+
+ self._assert_data(
+ [
+ {"a": 1, "b": 2, "c": 3, "id": 1},
+ {"a": 2, "b": 4, "c": 5, "id": 2},
+ ],
+ tablename="nopk",
+ )
+ eq_(
+ [col["name"] for col in inspect(config.db).get_columns("foo")],
+ ["id", "data", "x"],
+ )
+
def test_add_column_insert_before_recreate(self):
with self.op.batch_alter_table("foo", recreate="always") as batch_op:
batch_op.add_column(