This commit is contained in:
@@ -14,6 +14,7 @@ from sqlalchemy import inspect
|
||||
from sqlalchemy import Integer
|
||||
from sqlalchemy import MetaData
|
||||
from sqlalchemy import Numeric
|
||||
from sqlalchemy import PrimaryKeyConstraint
|
||||
from sqlalchemy import String
|
||||
from sqlalchemy import Table
|
||||
from sqlalchemy import Text
|
||||
@@ -149,6 +150,118 @@ class ModelOne:
|
||||
return m
|
||||
|
||||
|
||||
class NamingConvModel:
|
||||
__requires__ = ("unique_constraint_reflection",)
|
||||
configure_opts = {"conv_all_constraint_names": True}
|
||||
naming_convention = {
|
||||
"ix": "ix_%(column_0_label)s",
|
||||
"uq": "uq_%(table_name)s_%(constraint_name)s",
|
||||
"ck": "ck_%(table_name)s_%(constraint_name)s",
|
||||
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
|
||||
"pk": "pk_%(table_name)s",
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def _get_db_schema(cls):
|
||||
# database side - assume all constraints have a name that
|
||||
# we would assume here is a "db generated" name. need to make
|
||||
# sure these all render with op.f().
|
||||
m = MetaData()
|
||||
Table(
|
||||
"x1",
|
||||
m,
|
||||
Column("q", Integer),
|
||||
Index("db_x1_index_q", "q"),
|
||||
PrimaryKeyConstraint("q", name="db_x1_primary_q"),
|
||||
)
|
||||
Table(
|
||||
"x2",
|
||||
m,
|
||||
Column("q", Integer),
|
||||
Column("p", ForeignKey("x1.q", name="db_x2_foreign_q")),
|
||||
CheckConstraint("q > 5", name="db_x2_check_q"),
|
||||
)
|
||||
Table(
|
||||
"x3",
|
||||
m,
|
||||
Column("q", Integer),
|
||||
Column("r", Integer),
|
||||
Column("s", Integer),
|
||||
UniqueConstraint("q", name="db_x3_unique_q"),
|
||||
)
|
||||
Table(
|
||||
"x4",
|
||||
m,
|
||||
Column("q", Integer),
|
||||
PrimaryKeyConstraint("q", name="db_x4_primary_q"),
|
||||
)
|
||||
Table(
|
||||
"x5",
|
||||
m,
|
||||
Column("q", Integer),
|
||||
Column("p", ForeignKey("x4.q", name="db_x5_foreign_q")),
|
||||
Column("r", Integer),
|
||||
Column("s", Integer),
|
||||
PrimaryKeyConstraint("q", name="db_x5_primary_q"),
|
||||
UniqueConstraint("r", name="db_x5_unique_r"),
|
||||
CheckConstraint("s > 5", name="db_x5_check_s"),
|
||||
)
|
||||
# SQLite and it's "no names needed" thing. bleh.
|
||||
# we can't have a name for these so you'll see "None" for the name.
|
||||
Table(
|
||||
"unnamed_sqlite",
|
||||
m,
|
||||
Column("q", Integer),
|
||||
Column("r", Integer),
|
||||
PrimaryKeyConstraint("q"),
|
||||
UniqueConstraint("r"),
|
||||
)
|
||||
return m
|
||||
|
||||
@classmethod
|
||||
def _get_model_schema(cls):
|
||||
from sqlalchemy.sql.naming import conv
|
||||
|
||||
m = MetaData(naming_convention=cls.naming_convention)
|
||||
Table(
|
||||
"x1", m, Column("q", Integer, primary_key=True), Index(None, "q")
|
||||
)
|
||||
Table(
|
||||
"x2",
|
||||
m,
|
||||
Column("q", Integer),
|
||||
Column("p", ForeignKey("x1.q")),
|
||||
CheckConstraint("q > 5", name="token_x2check1"),
|
||||
)
|
||||
Table(
|
||||
"x3",
|
||||
m,
|
||||
Column("q", Integer),
|
||||
Column("r", Integer),
|
||||
Column("s", Integer),
|
||||
UniqueConstraint("r", name="token_x3r"),
|
||||
UniqueConstraint("s", name=conv("userdef_x3_unique_s")),
|
||||
)
|
||||
Table(
|
||||
"x4",
|
||||
m,
|
||||
Column("q", Integer, primary_key=True),
|
||||
Index("userdef_x4_idx_q", "q"),
|
||||
)
|
||||
Table(
|
||||
"x6",
|
||||
m,
|
||||
Column("q", Integer, primary_key=True),
|
||||
Column("p", ForeignKey("x4.q")),
|
||||
Column("r", Integer),
|
||||
Column("s", Integer),
|
||||
UniqueConstraint("r", name="token_x6r"),
|
||||
CheckConstraint("s > 5", "token_x6check1"),
|
||||
CheckConstraint("s < 20", conv("userdef_x6_check_s")),
|
||||
)
|
||||
return m
|
||||
|
||||
|
||||
class _ComparesFKs:
|
||||
def _assert_fk_diff(
|
||||
self,
|
||||
|
||||
@@ -6,9 +6,7 @@ from sqlalchemy import Table
|
||||
|
||||
from ._autogen_fixtures import AutogenFixtureTest
|
||||
from ... import testing
|
||||
from ...testing import config
|
||||
from ...testing import eq_
|
||||
from ...testing import exclusions
|
||||
from ...testing import is_
|
||||
from ...testing import is_true
|
||||
from ...testing import mock
|
||||
@@ -63,18 +61,8 @@ class AutogenerateComputedTest(AutogenFixtureTest, TestBase):
|
||||
c = diffs[0][3]
|
||||
eq_(c.name, "foo")
|
||||
|
||||
if config.requirements.computed_reflects_normally.enabled:
|
||||
is_true(isinstance(c.computed, sa.Computed))
|
||||
else:
|
||||
is_(c.computed, None)
|
||||
|
||||
if config.requirements.computed_reflects_as_server_default.enabled:
|
||||
is_true(isinstance(c.server_default, sa.DefaultClause))
|
||||
eq_(str(c.server_default.arg.text), "5")
|
||||
elif config.requirements.computed_reflects_normally.enabled:
|
||||
is_true(isinstance(c.computed, sa.Computed))
|
||||
else:
|
||||
is_(c.computed, None)
|
||||
is_true(isinstance(c.computed, sa.Computed))
|
||||
is_true(isinstance(c.server_default, sa.Computed))
|
||||
|
||||
@testing.combinations(
|
||||
lambda: (None, sa.Computed("bar*5")),
|
||||
@@ -85,7 +73,6 @@ class AutogenerateComputedTest(AutogenFixtureTest, TestBase):
|
||||
),
|
||||
lambda: (sa.Computed("bar*5"), sa.Computed("bar * 42")),
|
||||
)
|
||||
@config.requirements.computed_reflects_normally
|
||||
def test_cant_change_computed_warning(self, test_case):
|
||||
arg_before, arg_after = testing.resolve_lambda(test_case, **locals())
|
||||
m1 = MetaData()
|
||||
@@ -124,10 +111,7 @@ class AutogenerateComputedTest(AutogenFixtureTest, TestBase):
|
||||
lambda: (None, None),
|
||||
lambda: (sa.Computed("5"), sa.Computed("5")),
|
||||
lambda: (sa.Computed("bar*5"), sa.Computed("bar*5")),
|
||||
(
|
||||
lambda: (sa.Computed("bar*5"), None),
|
||||
config.requirements.computed_doesnt_reflect_as_server_default,
|
||||
),
|
||||
lambda: (sa.Computed("bar*5"), sa.Computed("bar * \r\n\t5")),
|
||||
)
|
||||
def test_computed_unchanged(self, test_case):
|
||||
arg_before, arg_after = testing.resolve_lambda(test_case, **locals())
|
||||
@@ -158,46 +142,3 @@ class AutogenerateComputedTest(AutogenFixtureTest, TestBase):
|
||||
eq_(mock_warn.mock_calls, [])
|
||||
|
||||
eq_(list(diffs), [])
|
||||
|
||||
@config.requirements.computed_reflects_as_server_default
|
||||
def test_remove_computed_default_on_computed(self):
|
||||
"""Asserts the current behavior which is that on PG and Oracle,
|
||||
the GENERATED ALWAYS AS is reflected as a server default which we can't
|
||||
tell is actually "computed", so these come out as a modification to
|
||||
the server default.
|
||||
|
||||
"""
|
||||
m1 = MetaData()
|
||||
m2 = MetaData()
|
||||
|
||||
Table(
|
||||
"user",
|
||||
m1,
|
||||
Column("id", Integer, primary_key=True),
|
||||
Column("bar", Integer),
|
||||
Column("foo", Integer, sa.Computed("bar + 42")),
|
||||
)
|
||||
|
||||
Table(
|
||||
"user",
|
||||
m2,
|
||||
Column("id", Integer, primary_key=True),
|
||||
Column("bar", Integer),
|
||||
Column("foo", Integer),
|
||||
)
|
||||
|
||||
diffs = self._fixture(m1, m2)
|
||||
|
||||
eq_(diffs[0][0][0], "modify_default")
|
||||
eq_(diffs[0][0][2], "user")
|
||||
eq_(diffs[0][0][3], "foo")
|
||||
old = diffs[0][0][-2]
|
||||
new = diffs[0][0][-1]
|
||||
|
||||
is_(new, None)
|
||||
is_true(isinstance(old, sa.DefaultClause))
|
||||
|
||||
if exclusions.against(config, "postgresql"):
|
||||
eq_(str(old.arg.text), "(bar + 42)")
|
||||
elif exclusions.against(config, "oracle"):
|
||||
eq_(str(old.arg.text), '"BAR"+42')
|
||||
|
||||
@@ -24,9 +24,9 @@ class MigrationTransactionTest(TestBase):
|
||||
self.context = MigrationContext.configure(
|
||||
dialect=conn.dialect, opts=opts
|
||||
)
|
||||
self.context.output_buffer = (
|
||||
self.context.impl.output_buffer
|
||||
) = io.StringIO()
|
||||
self.context.output_buffer = self.context.impl.output_buffer = (
|
||||
io.StringIO()
|
||||
)
|
||||
else:
|
||||
self.context = MigrationContext.configure(
|
||||
connection=conn, opts=opts
|
||||
|
||||
Reference in New Issue
Block a user