summaryrefslogtreecommitdiff
path: root/tests/test_batch.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2019-06-25 11:40:56 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2019-06-25 16:31:43 -0400
commitd4951ffb66f933ca332baf85faa15c7547523ecb (patch)
tree2d783ac42d6657f423cf36a56e624e402f8da828 /tests/test_batch.py
parent26453a8b284743bd590a86208968ca862caa67ca (diff)
downloadalembic-d4951ffb66f933ca332baf85faa15c7547523ecb.tar.gz
Ensure SQLite default expressions are parenthesized
- SQLite server default reflection will ensure parenthesis are surrounding a column default expression that is detected as being a non-constant expression, such as a ``datetime()`` default, to accommodate for the requirement that SQL expressions have to be parenthesized when being sent as DDL. Parenthesis are not added to constant expressions to allow for maximum cross-compatibility with other dialects and existing test suites (such as Alembic's), which necessarily entails scanning the expression to eliminate for constant numeric and string values. The logic is added to the two "reflection->DDL round trip" paths which are currently autogenerate and batch migration. Within autogenerate, the logic is on the rendering side, whereas in batch the logic is installed as a column reflection hook. - Improved SQLite server default comparison to accommodate for a ``text()`` construct that added parenthesis directly vs. a construct that relied upon the SQLAlchemy SQLite dialect to render the parenthesis, as well as improved support for various forms of constant expressions such as values that are quoted vs. non-quoted. - Fixed bug where the "literal_binds" flag was not being set when autogenerate would create a server default value, meaning server default comparisons would fail for functions that contained literal values. Fixes: #579 Change-Id: I78b87573b8ecd15cb4ced08f054902f574e3956c
Diffstat (limited to 'tests/test_batch.py')
-rw-r--r--tests/test_batch.py41
1 files changed, 41 insertions, 0 deletions
diff --git a/tests/test_batch.py b/tests/test_batch.py
index 8879c9c..c8c5b33 100644
--- a/tests/test_batch.py
+++ b/tests/test_batch.py
@@ -9,6 +9,7 @@ from sqlalchemy import Enum
from sqlalchemy import exc
from sqlalchemy import ForeignKey
from sqlalchemy import ForeignKeyConstraint
+from sqlalchemy import func
from sqlalchemy import Index
from sqlalchemy import Integer
from sqlalchemy import MetaData
@@ -1117,6 +1118,23 @@ class BatchRoundTripTest(TestBase):
t.create(self.conn)
return t
+ def _datetime_server_default_fixture(self):
+ return func.datetime("now", "localtime")
+
+ def _timestamp_w_expr_default_fixture(self):
+ t = Table(
+ "hasts",
+ self.metadata,
+ Column(
+ "x",
+ DateTime(),
+ server_default=self._datetime_server_default_fixture(),
+ nullable=False,
+ ),
+ )
+ t.create(self.conn)
+ return t
+
def _int_to_boolean_fixture(self):
t = Table("hasbool", self.metadata, Column("x", Integer))
t.create(self.conn)
@@ -1157,6 +1175,23 @@ class BatchRoundTripTest(TestBase):
[(datetime.datetime(2012, 5, 18, 15, 32, 5),)],
)
+ @config.requirements.sqlalchemy_12
+ def test_no_net_change_timestamp_w_default(self):
+ t = self._timestamp_w_expr_default_fixture()
+
+ with self.op.batch_alter_table("hasts") as batch_op:
+ batch_op.alter_column(
+ "x",
+ type_=DateTime(),
+ nullable=False,
+ server_default=self._datetime_server_default_fixture(),
+ )
+
+ self.conn.execute(t.insert())
+
+ row = self.conn.execute(select([t.c.x])).fetchone()
+ assert row["x"] is not None
+
def test_drop_col_schematype(self):
self._boolean_fixture()
with self.op.batch_alter_table("hasbool") as batch_op:
@@ -1612,6 +1647,9 @@ class BatchRoundTripMySQLTest(BatchRoundTripTest):
__only_on__ = "mysql"
__backend__ = True
+ def _datetime_server_default_fixture(self):
+ return func.current_timestamp()
+
@exclusions.fails()
def test_drop_pk_col_readd_pk_col(self):
super(BatchRoundTripMySQLTest, self).test_drop_pk_col_readd_pk_col()
@@ -1655,6 +1693,9 @@ class BatchRoundTripPostgresqlTest(BatchRoundTripTest):
__only_on__ = "postgresql"
__backend__ = True
+ def _datetime_server_default_fixture(self):
+ return func.current_timestamp()
+
@exclusions.fails()
def test_drop_pk_col_readd_pk_col(self):
super(