Commit f46d7314 authored by Aymeric Augustin's avatar Aymeric Augustin
Browse files

Fixed #19677 -- Introspection of recursive foreign keys under SQLite.

Thanks Simon Charette.
parent 14d1d504
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ class BaseDatabaseCreation(object):
                    field_output.append(tablespace_sql)
            if f.rel:
                ref_output, pending = self.sql_for_inline_foreign_key_references(
                    f, known_models, style)
                    model, f, known_models, style)
                if pending:
                    pending_references.setdefault(f.rel.to, []).append(
                        (model, f))
@@ -116,15 +116,16 @@ class BaseDatabaseCreation(object):

        return final_output, pending_references

    def sql_for_inline_foreign_key_references(self, field, known_models, style):
    def sql_for_inline_foreign_key_references(self, model, field, known_models, style):
        """
        Return the SQL snippet defining the foreign key reference for a field.
        """
        qn = self.connection.ops.quote_name
        if field.rel.to in known_models:
        rel_to = field.rel.to
        if rel_to in known_models or rel_to == model:
            output = [style.SQL_KEYWORD('REFERENCES') + ' ' +
                style.SQL_TABLE(qn(field.rel.to._meta.db_table)) + ' (' +
                style.SQL_FIELD(qn(field.rel.to._meta.get_field(
                style.SQL_TABLE(qn(rel_to._meta.db_table)) + ' (' +
                style.SQL_FIELD(qn(rel_to._meta.get_field(
                    field.rel.field_name).column)) + ')' +
                self.connection.ops.deferrable_sql()
            ]
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ class DatabaseCreation(BaseDatabaseCreation):
            suffix.append('COLLATE %s' % self.connection.settings_dict['TEST_COLLATION'])
        return ' '.join(suffix)

    def sql_for_inline_foreign_key_references(self, field, known_models, style):
    def sql_for_inline_foreign_key_references(self, model, field, known_models, style):
        "All inline references are pending under MySQL"
        return [], True

+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ class Article(models.Model):
    headline = models.CharField(max_length=100)
    pub_date = models.DateField()
    reporter = models.ForeignKey(Reporter)
    response_to = models.ForeignKey('self', null=True)

    def __str__(self):
        return self.headline
+6 −2
Original line number Diff line number Diff line
@@ -106,13 +106,17 @@ class IntrospectionTests(TestCase):
        # should test that the response is correct.
        if relations:
            # That's {field_index: (field_index_other_table, other_table)}
            self.assertEqual(relations, {3: (0, Reporter._meta.db_table)})
            self.assertEqual(relations, {3: (0, Reporter._meta.db_table),
                                         4: (0, Article._meta.db_table)})

    @skipUnlessDBFeature('can_introspect_foreign_keys')
    def test_get_key_columns(self):
        cursor = connection.cursor()
        key_columns = connection.introspection.get_key_columns(cursor, Article._meta.db_table)
        self.assertEqual(key_columns, [('reporter_id', Reporter._meta.db_table, 'id')])
        self.assertEqual(
            set(key_columns),
            set([('reporter_id', Reporter._meta.db_table, 'id'),
                 ('response_to_id', Article._meta.db_table, 'id')]))

    def test_get_primary_key_column(self):
        cursor = connection.cursor()