Skip to content

Commit ca822f7

Browse files
committed
Fixed a very strange error droping field with check constraints
Related to issue 154 Tested in firebird 3.0.x
1 parent 3e33a1d commit ca822f7

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

firebird/introspection.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,12 @@ def get_indexes(self, cursor, table_name):
186186
cursor.execute("""
187187
SELECT
188188
LOWER(s.RDB$FIELD_NAME) AS field_name,
189-
189+
190190
LOWER(case
191191
when rc.RDB$CONSTRAINT_TYPE is not null then rc.RDB$CONSTRAINT_TYPE
192192
else 'INDEX'
193193
end) AS constraint_type
194-
194+
195195
FROM RDB$INDEX_SEGMENTS s
196196
LEFT JOIN RDB$INDICES i ON i.RDB$INDEX_NAME = s.RDB$INDEX_NAME
197197
LEFT JOIN RDB$RELATION_CONSTRAINTS rc ON rc.RDB$INDEX_NAME = s.RDB$INDEX_NAME
@@ -250,7 +250,7 @@ def get_constraints(self, cursor, table_name):
250250
when s.RDB$FIELD_NAME is not null then s.RDB$FIELD_NAME
251251
else ''
252252
end AS field_name,
253-
253+
254254
i2.RDB$RELATION_NAME AS references_table,
255255
s2.RDB$FIELD_NAME AS references_field,
256256
i.RDB$UNIQUE_FLAG,
@@ -329,6 +329,21 @@ def _get_field_indexes(self, cursor, table_name, field_name):
329329

330330
return [index_name[0].strip() for index_name in cursor.fetchall()]
331331

332+
def _get_check_constraints(self, cursor, table_name, field_name):
333+
table = "'%s'" % table_name.upper()
334+
field = "'%s'" % field_name.upper()
335+
cursor.execute("""
336+
select distinct rc.rdb$constraint_name as check_constraint_name
337+
from rdb$relation_constraints rc
338+
join rdb$check_constraints cc on rc.rdb$constraint_name = cc.rdb$constraint_name
339+
join rdb$triggers c on cc.rdb$trigger_name = c.rdb$trigger_name
340+
join rdb$relation_fields rf on rc.rdb$relation_name = rf.rdb$relation_name
341+
where rc.rdb$relation_name = %s
342+
and rf.rdb$field_name = %s
343+
and rc.rdb$constraint_type = 'CHECK'
344+
""" % (table, field,))
345+
return [cn[0].strip() for cn in cursor.fetchall()]
346+
332347
def _name_to_index(self, cursor, table_name):
333348
"""Return a dictionary of {field_name: field_index} for the given table.
334349
Indexes are 0-based.

firebird/schema.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ def _alter_column_set_null(self, table_name, column_name, is_null):
4747
engine_ver = str(self.connection.connection.engine_version).split('.')
4848
if engine_ver and len(engine_ver) > 0 and int(engine_ver[0]) >= 3:
4949
sql = """
50-
ALTER TABLE \"%(table_name)s\"
51-
ALTER \"%(column)s\"
50+
ALTER TABLE \"%(table_name)s\"
51+
ALTER \"%(column)s\"
5252
%(null_flag)s NOT NULL
5353
"""
5454
null_flag = 'DROP' if is_null else 'SET'
@@ -237,6 +237,12 @@ def _get_field_indexes(self, model, field):
237237
indexes = self.connection.introspection._get_field_indexes(cursor, model._meta.db_table, field.column)
238238
return indexes
239239

240+
def _get_field_check_constraints(self, model, field):
241+
with self.connection.cursor() as cursor:
242+
db_table = model._meta.db_table
243+
checks = self.connection.introspection._get_check_constraints(cursor, db_table, field.column)
244+
return checks
245+
240246
def remove_field(self, model, field):
241247
# If remove a AutoField, we need remove all related stuff
242248
# if isinstance(field, AutoField):
@@ -252,6 +258,11 @@ def remove_field(self, model, field):
252258
sql = self._delete_constraint_sql(self.sql_delete_index, model, index_name)
253259
self.execute(sql)
254260

261+
# If field has check constraint, then remove it first
262+
for check_constraint_name in self._get_field_check_constraints(model, field):
263+
sql = self._delete_constraint_sql(self.sql_delete_constraint, model, check_constraint_name)
264+
self.execute(sql)
265+
255266
super(DatabaseSchemaEditor, self).remove_field(model, field)
256267

257268
def _alter_column_type_sql(self, table, old_field, new_field, new_type):
@@ -875,4 +886,4 @@ def execute(self, sql, params=[]):
875886
except Exception as e:
876887
raise e
877888
else:
878-
super(DatabaseSchemaEditor, self).execute(sql, params)
889+
super(DatabaseSchemaEditor, self).execute(sql, params)

0 commit comments

Comments
 (0)