1from sqlalchemy.testing.requirements import Requirements
2
3from alembic import util
4from alembic.util import sqla_compat
5from ..testing import exclusions
6
7
8class SuiteRequirements(Requirements):
9    @property
10    def schemas(self):
11        """Target database must support external schemas, and have one
12        named 'test_schema'."""
13
14        return exclusions.open()
15
16    @property
17    def autocommit_isolation(self):
18        """target database should support 'AUTOCOMMIT' isolation level"""
19
20        return exclusions.closed()
21
22    @property
23    def unique_constraint_reflection(self):
24        def doesnt_have_check_uq_constraints(config):
25            from sqlalchemy import inspect
26
27            insp = inspect(config.db)
28            try:
29                insp.get_unique_constraints("x")
30            except NotImplementedError:
31                return True
32            except TypeError:
33                return True
34            except Exception:
35                pass
36            return False
37
38        return exclusions.skip_if(doesnt_have_check_uq_constraints)
39
40    @property
41    def sequences(self):
42        """Target database must support SEQUENCEs."""
43
44        return exclusions.only_if(
45            [lambda config: config.db.dialect.supports_sequences],
46            "no sequence support",
47        )
48
49    @property
50    def foreign_key_match(self):
51        return exclusions.open()
52
53    @property
54    def foreign_key_constraint_reflection(self):
55        return exclusions.open()
56
57    @property
58    def check_constraints_w_enforcement(self):
59        """Target database must support check constraints
60        and also enforce them."""
61
62        return exclusions.open()
63
64    @property
65    def reflects_pk_names(self):
66        return exclusions.closed()
67
68    @property
69    def reflects_fk_options(self):
70        return exclusions.closed()
71
72    @property
73    def sqlalchemy_13(self):
74        return exclusions.skip_if(
75            lambda config: not util.sqla_13,
76            "SQLAlchemy 1.3 or greater required",
77        )
78
79    @property
80    def sqlalchemy_14(self):
81        return exclusions.skip_if(
82            lambda config: not util.sqla_14,
83            "SQLAlchemy 1.4 or greater required",
84        )
85
86    @property
87    def sqlalchemy_1x(self):
88        return exclusions.skip_if(
89            lambda config: not util.sqla_1x,
90            "SQLAlchemy 1.x test",
91        )
92
93    @property
94    def comments(self):
95        return exclusions.only_if(
96            lambda config: config.db.dialect.supports_comments
97        )
98
99    @property
100    def alter_column(self):
101        return exclusions.open()
102
103    @property
104    def computed_columns(self):
105        return exclusions.closed()
106
107    @property
108    def computed_columns_api(self):
109        return exclusions.only_if(
110            exclusions.BooleanPredicate(sqla_compat.has_computed)
111        )
112
113    @property
114    def computed_reflects_normally(self):
115        return exclusions.only_if(
116            exclusions.BooleanPredicate(sqla_compat.has_computed_reflection)
117        )
118
119    @property
120    def computed_reflects_as_server_default(self):
121        return exclusions.closed()
122
123    @property
124    def computed_doesnt_reflect_as_server_default(self):
125        return exclusions.closed()
126
127    @property
128    def autoincrement_on_composite_pk(self):
129        return exclusions.closed()
130
131    @property
132    def fk_ondelete_is_reflected(self):
133        return exclusions.closed()
134
135    @property
136    def fk_onupdate_is_reflected(self):
137        return exclusions.closed()
138
139    @property
140    def fk_onupdate(self):
141        return exclusions.open()
142
143    @property
144    def fk_ondelete_restrict(self):
145        return exclusions.open()
146
147    @property
148    def fk_onupdate_restrict(self):
149        return exclusions.open()
150
151    @property
152    def fk_ondelete_noaction(self):
153        return exclusions.open()
154
155    @property
156    def fk_initially(self):
157        return exclusions.closed()
158
159    @property
160    def fk_deferrable(self):
161        return exclusions.closed()
162
163    @property
164    def fk_deferrable_is_reflected(self):
165        return exclusions.closed()
166
167    @property
168    def fk_names(self):
169        return exclusions.open()
170
171    @property
172    def integer_subtype_comparisons(self):
173        return exclusions.open()
174
175    @property
176    def no_name_normalize(self):
177        return exclusions.skip_if(
178            lambda config: config.db.dialect.requires_name_normalize
179        )
180
181    @property
182    def identity_columns(self):
183        return exclusions.closed()
184
185    @property
186    def identity_columns_alter(self):
187        return exclusions.closed()
188
189    @property
190    def identity_columns_api(self):
191        return exclusions.only_if(
192            exclusions.BooleanPredicate(sqla_compat.has_identity)
193        )
194
195    @property
196    def supports_identity_on_null(self):
197        return exclusions.closed()
198