diff --git a/CHANGES.rst b/CHANGES.rst index f5e02c5..f13cbb3 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -24,6 +24,7 @@ Bug Fixes: * #134 inspectdb should suppress output 'id = AutoField(primary_key=True)' * #134 fix for decreasing size of column with default by create-copy-drop-rename strategy. +* #118 fix constraint creation using the wrong table and column name. Thanks to BlueMagma. 3.0.0 (2022/02/27) ------------------ diff --git a/django_redshift_backend/base.py b/django_redshift_backend/base.py index cb59bf9..b0f02a5 100644 --- a/django_redshift_backend/base.py +++ b/django_redshift_backend/base.py @@ -270,8 +270,8 @@ def create_model(self, model): params.extend(extra_params) # FK if field.remote_field and field.db_constraint: - to_table = field.remote_field.related_model._meta.db_table - to_column = field.remote_field.related_model._meta.get_field( + to_table = field.remote_field.model._meta.db_table + to_column = field.remote_field.model._meta.get_field( field.remote_field.field_name ).column if self.connection.features.supports_foreign_keys: diff --git a/tests/test_migrations.py b/tests/test_migrations.py index 62416fd..c338fdf 100644 --- a/tests/test_migrations.py +++ b/tests/test_migrations.py @@ -504,3 +504,61 @@ def test_alter_type_binary_to_char(self): '''ALTER TABLE test_pony DROP COLUMN "hash" CASCADE;''', '''ALTER TABLE test_pony RENAME COLUMN "hash_tmp" TO "hash";''', ], sqls) + + @postgres_fixture() + def test_foreign_key_to_id(self): + new_state = self.set_up_test_model('test') + operations = [ + migrations.CreateModel( + 'Rider', + [ + ('id', models.AutoField(primary_key=True)), + ('pony', models.ForeignKey('Pony', models.CASCADE)), + ], + ), + ] + with self.collect_sql() as sqls: + self.apply_operations('test', new_state, operations) + + if TEST_WITH_POSTGRES: + identity = "serial" + elif TEST_WITH_REDSHIFT: + identity = "integer identity(1, 1)" + + self.assertEqual([ + f'''CREATE TABLE "test_rider" ("id" {identity} NOT NULL PRIMARY KEY, "pony_id" integer NOT NULL) ;''', + '''ALTER TABLE "test_rider" ADD CONSTRAINT "test_rider_pony_id_3c028c84_fk_test_pony_id"''' + ''' FOREIGN KEY ("pony_id") REFERENCES "test_pony" ("id");''', + ], sqls) + + @postgres_fixture() + def test_foreign_key_to_non_id(self): + new_state = self.set_up_test_model('test') + operations = [ + migrations.AddField( + model_name='Pony', + name='remote', + field=models.IntegerField(unique=True, null=True), + ), + migrations.CreateModel( + 'Rider', + [ + ('id', models.AutoField(primary_key=True)), + ('pony_remote', models.ForeignKey('Pony', on_delete=models.CASCADE, to_field="remote")), + ], + ), + ] + with self.collect_sql() as sqls: + self.apply_operations('test', new_state, operations) + + if TEST_WITH_POSTGRES: + identity = "serial" + elif TEST_WITH_REDSHIFT: + identity = "integer identity(1, 1)" + + self.assertEqual([ + '''ALTER TABLE "test_pony" ADD COLUMN "remote" integer NULL;''', + f'''CREATE TABLE "test_rider" ("id" {identity} NOT NULL PRIMARY KEY, "pony_remote_id" integer NOT NULL) ;''', + '''ALTER TABLE "test_pony" ADD CONSTRAINT "test_pony_remote_e347b432_uniq" UNIQUE ("remote");''', + '''ALTER TABLE "test_rider" ADD CONSTRAINT "test_rider_pony_remote_id_269d66d9_fk_test_pony_remote" FOREIGN KEY ("pony_remote_id") REFERENCES "test_pony" ("remote");''' + ], sqls)