Skip to content

Commit 9a533af

Browse files
author
Jesse Whitehouse
committed
Add test fixture overrides so we can run more tests.
I've found that the test_get_multi_foreign_keys test fails on occasion due to a sorting issue. Our dialect returns the correct information. But the test fixture does a comparison _by position_ of the returned values. And since we return the information in a different order than is specified by the test, it fails. This is not a blocker to merge as I'm confident our get_foreign_keys method behaves as it should (after all, test_get_foreign_keys passes). But we should re-evaluate this later Signed-off-by: Jesse Whitehouse <jesse.whitehouse@databricks.com>
1 parent ee474ad commit 9a533af

5 files changed

Lines changed: 263 additions & 2 deletions

File tree

src/databricks/sqlalchemy/test/_future.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,26 @@ def test_get_view_definition_does_not_exist(self):
298298
def test_get_multi_pk_constraint(self):
299299
pass
300300

301+
@pytest.mark.skip(render_future_feature(FutureFeature.CHECK))
302+
def test_get_multi_check_constraints(self):
303+
pass
304+
305+
@pytest.mark.skip(reason=render_future_feature(FutureFeature.TBL_COMMENTS))
306+
def test_get_comments(self):
307+
pass
308+
309+
@pytest.mark.skip(reason=render_future_feature(FutureFeature.TBL_COMMENTS))
310+
def test_get_comments_with_schema(self):
311+
pass
312+
313+
@pytest.mark.skip(reason=render_future_feature(FutureFeature.TBL_COMMENTS))
314+
def test_comments_unicode(self):
315+
pass
316+
317+
@pytest.mark.skip(reason=render_future_feature(FutureFeature.TBL_COMMENTS))
318+
def test_comments_unicode_full(self):
319+
pass
320+
301321

302322
class ComponentReflectionTestExtra(ComponentReflectionTestExtra):
303323
@pytest.mark.skip(render_future_feature(FutureFeature.CHECK))

src/databricks/sqlalchemy/test/_regression.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@
55
ArgSignatureTest,
66
BooleanTest,
77
CastTypeDecoratorTest,
8-
ComponentReflectionTest,
98
ComponentReflectionTestExtra,
109
CompositeKeyReflectionTest,
1110
CompoundSelectTest,
12-
CTETest,
1311
DateHistoricTest,
1412
DateTest,
1513
DateTimeCoercedToDateTimeTest,
@@ -53,6 +51,11 @@
5351
ValuesExpressionTest,
5452
)
5553

54+
from databricks.sqlalchemy.test.overrides._ctetest import CTETest
55+
from databricks.sqlalchemy.test.overrides._componentreflectiontest import (
56+
ComponentReflectionTest,
57+
)
58+
5659

5760
@pytest.mark.reviewed
5861
class NumericTest(NumericTest):

src/databricks/sqlalchemy/test/_unsupported.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,22 @@ def test_get_temp_table_unique_constraints(self):
292292
def test_reflect_table_temp_table(self):
293293
pass
294294

295+
@pytest.mark.skip(render_skip_reason(SkipReason.INDEXES))
296+
def test_get_indexes(self):
297+
pass
298+
299+
@pytest.mark.skip(render_skip_reason(SkipReason.INDEXES))
300+
def test_multi_indexes(self):
301+
pass
302+
303+
@pytest.mark.skip(render_skip_reason(SkipReason.INDEXES))
304+
def get_noncol_index(self):
305+
pass
306+
307+
@pytest.mark.skip(render_skip_reason(SkipReason.UNIQUE))
308+
def test_get_unique_constraints(self):
309+
pass
310+
295311

296312
class NumericTest(NumericTest):
297313
@pytest.mark.skip(render_skip_reason(SkipReason.DECIMAL_FEAT))
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
"""The default test setup uses self-referential foreign keys and indexes for a test table.
2+
We override to remove these assumptions.
3+
4+
Note that test_multi_foreign_keys currently does not pass for all combinations due to
5+
an ordering issue. The dialect returns the expected information. But this test makes assertions
6+
on the order of the returned results. We can't guarantee that order at the moment.
7+
8+
The test fixture actually tries to sort the outputs, but this sort isn't working. Will need
9+
to follow-up on this later.
10+
"""
11+
import sqlalchemy as sa
12+
from sqlalchemy.testing import config
13+
from sqlalchemy.testing.schema import Column
14+
from sqlalchemy.testing.schema import Table
15+
from sqlalchemy import ForeignKey
16+
from sqlalchemy import testing
17+
18+
from sqlalchemy.testing.suite.test_reflection import ComponentReflectionTest
19+
20+
21+
class ComponentReflectionTest(ComponentReflectionTest):
22+
@classmethod
23+
def define_reflected_tables(cls, metadata, schema):
24+
if schema:
25+
schema_prefix = schema + "."
26+
else:
27+
schema_prefix = ""
28+
29+
if testing.requires.self_referential_foreign_keys.enabled:
30+
parent_id_args = (
31+
ForeignKey(
32+
"%susers.user_id" % schema_prefix, name="user_id_fk", use_alter=True
33+
),
34+
)
35+
else:
36+
parent_id_args = ()
37+
users = Table(
38+
"users",
39+
metadata,
40+
Column("user_id", sa.INT, primary_key=True),
41+
Column("test1", sa.CHAR(5), nullable=False),
42+
Column("test2", sa.Float(), nullable=False),
43+
Column("parent_user_id", sa.Integer, *parent_id_args),
44+
sa.CheckConstraint(
45+
"test2 > 0",
46+
name="zz_test2_gt_zero",
47+
comment="users check constraint",
48+
),
49+
sa.CheckConstraint("test2 <= 1000"),
50+
schema=schema,
51+
test_needs_fk=True,
52+
)
53+
54+
Table(
55+
"dingalings",
56+
metadata,
57+
Column("dingaling_id", sa.Integer, primary_key=True),
58+
Column(
59+
"address_id",
60+
sa.Integer,
61+
ForeignKey(
62+
"%semail_addresses.address_id" % schema_prefix,
63+
name="zz_email_add_id_fg",
64+
comment="di fk comment",
65+
),
66+
),
67+
Column(
68+
"id_user",
69+
sa.Integer,
70+
ForeignKey("%susers.user_id" % schema_prefix),
71+
),
72+
Column("data", sa.String(30), unique=True),
73+
sa.CheckConstraint(
74+
"address_id > 0 AND address_id < 1000",
75+
name="address_id_gt_zero",
76+
),
77+
sa.UniqueConstraint(
78+
"address_id",
79+
"dingaling_id",
80+
name="zz_dingalings_multiple",
81+
comment="di unique comment",
82+
),
83+
schema=schema,
84+
test_needs_fk=True,
85+
)
86+
Table(
87+
"email_addresses",
88+
metadata,
89+
Column("address_id", sa.Integer),
90+
Column("remote_user_id", sa.Integer, ForeignKey(users.c.user_id)),
91+
Column("email_address", sa.String(20)),
92+
sa.PrimaryKeyConstraint(
93+
"address_id", name="email_ad_pk", comment="ea pk comment"
94+
),
95+
schema=schema,
96+
test_needs_fk=True,
97+
)
98+
Table(
99+
"comment_test",
100+
metadata,
101+
Column("id", sa.Integer, primary_key=True, comment="id comment"),
102+
Column("data", sa.String(20), comment="data % comment"),
103+
Column(
104+
"d2",
105+
sa.String(20),
106+
comment=r"""Comment types type speedily ' " \ '' Fun!""",
107+
),
108+
Column("d3", sa.String(42), comment="Comment\nwith\rescapes"),
109+
schema=schema,
110+
comment=r"""the test % ' " \ table comment""",
111+
)
112+
Table(
113+
"no_constraints",
114+
metadata,
115+
Column("data", sa.String(20)),
116+
schema=schema,
117+
comment="no\nconstraints\rhas\fescaped\vcomment",
118+
)
119+
120+
if testing.requires.cross_schema_fk_reflection.enabled:
121+
if schema is None:
122+
Table(
123+
"local_table",
124+
metadata,
125+
Column("id", sa.Integer, primary_key=True),
126+
Column("data", sa.String(20)),
127+
Column(
128+
"remote_id",
129+
ForeignKey("%s.remote_table_2.id" % testing.config.test_schema),
130+
),
131+
test_needs_fk=True,
132+
schema=config.db.dialect.default_schema_name,
133+
)
134+
else:
135+
Table(
136+
"remote_table",
137+
metadata,
138+
Column("id", sa.Integer, primary_key=True),
139+
Column(
140+
"local_id",
141+
ForeignKey(
142+
"%s.local_table.id" % config.db.dialect.default_schema_name
143+
),
144+
),
145+
Column("data", sa.String(20)),
146+
schema=schema,
147+
test_needs_fk=True,
148+
)
149+
Table(
150+
"remote_table_2",
151+
metadata,
152+
Column("id", sa.Integer, primary_key=True),
153+
Column("data", sa.String(20)),
154+
schema=schema,
155+
test_needs_fk=True,
156+
)
157+
158+
if testing.requires.index_reflection.enabled:
159+
Index("users_t_idx", users.c.test1, users.c.test2, unique=True)
160+
Index("users_all_idx", users.c.user_id, users.c.test2, users.c.test1)
161+
162+
if not schema:
163+
# test_needs_fk is at the moment to force MySQL InnoDB
164+
noncol_idx_test_nopk = Table(
165+
"noncol_idx_test_nopk",
166+
metadata,
167+
Column("q", sa.String(5)),
168+
test_needs_fk=True,
169+
)
170+
171+
noncol_idx_test_pk = Table(
172+
"noncol_idx_test_pk",
173+
metadata,
174+
Column("id", sa.Integer, primary_key=True),
175+
Column("q", sa.String(5)),
176+
test_needs_fk=True,
177+
)
178+
179+
if (
180+
testing.requires.indexes_with_ascdesc.enabled
181+
and testing.requires.reflect_indexes_with_ascdesc.enabled
182+
):
183+
Index("noncol_idx_nopk", noncol_idx_test_nopk.c.q.desc())
184+
Index("noncol_idx_pk", noncol_idx_test_pk.c.q.desc())
185+
186+
if testing.requires.view_column_reflection.enabled:
187+
cls.define_views(metadata, schema)
188+
if not schema and testing.requires.temp_table_reflection.enabled:
189+
cls.define_temp_tables(metadata)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""The default test setup uses a self-referential foreign key. With our dialect this requires
2+
`use_alter=True` and the fk constraint to be named. So we override this to make the test pass.
3+
"""
4+
5+
from sqlalchemy.testing.suite import CTETest
6+
7+
from sqlalchemy.testing.schema import Column
8+
from sqlalchemy.testing.schema import Table
9+
from sqlalchemy import ForeignKey
10+
from sqlalchemy import Integer
11+
from sqlalchemy import String
12+
13+
14+
class CTETest(CTETest):
15+
@classmethod
16+
def define_tables(cls, metadata):
17+
Table(
18+
"some_table",
19+
metadata,
20+
Column("id", Integer, primary_key=True),
21+
Column("data", String(50)),
22+
Column(
23+
"parent_id", ForeignKey("some_table.id", name="fk_test", use_alter=True)
24+
),
25+
)
26+
27+
Table(
28+
"some_other_table",
29+
metadata,
30+
Column("id", Integer, primary_key=True),
31+
Column("data", String(50)),
32+
Column("parent_id", Integer),
33+
)

0 commit comments

Comments
 (0)