Django model relationships without running migration on existing database
Tags: python, django, backend, webdev
Published: 2019-07-29 12:31:53

---
title: Django model relationships without running migration on existing database
published: true
description: There are use cases where we are working on a legacy system and are not allow to change/alter the DB constraints, but want to utilise the Djando ORM features as well. This post will help to create Django model relationship constraints without running migration on existing database.
tags: python, django, backend, webdev
cover_image: https://res.cloudinary.com/idr/image/upload/w_1000,ar_16:9,c_fill,g_auto,e_sharpen/v1564290803/dev.to/nvrs.jpg
---
In my previous post, we discussed about how we can create Django models of existing database with the command `inspectdb`. Extending to that post, in this post, we will try to create a foreign key relationship between models where our existing tables do not have foreign key constraints. Also, as it is legacy system, our use-case is to not run migrations of these constraints.
{% link idrisrampurawala/creating-django-models-of-an-existing-db-288m %} 

# Problem
* We have created Django models of our existing database
* Our existing database do not have any foreign key constraint on any table
* We want to utilize Django-ORM to query related tables
* We do not want to migrate/create these constraints in existing database, so our database will be untouched

# Solution
To achieve this, let's consider following Django models as an example
```python
class Manufacturer(models.Model):
    pass

class Car(models.Model):
    manufacturer_id = models.IntegerField()
```
Of course, our motive is to change the model where the `manufacturer_id` `IntegerField` becomes a  `manufacturer`  `ForeignKey` i.e.
```python
class Manufacturer(models.Model):
    pass

class Car(models.Model):
    manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE,
                                     related_name="manufacturer")
```

This can be achieved in 2 steps:
## Step 1 - Modify the field in Django model
We will modify the `IntegerField` to `ForeignKey` field
```python
class Car(models.Model):
    manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE,
                                     related_name="manufacturer")
```

## Step 2 - Add dummy migration entry
We will manually create a migration file under `appName/migrations`
```python
# Generated manually

from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        # Car - Manufacturer Relation
        migrations.AlterField(
            model_name='Car',
            name='manufacturer_id',
            field=models.IntegerField(db_column='manufacturer_id')
        ),
        migrations.RenameField(
            model_name='Car',
            old_name='manufacturer_id',
            new_name='manufacturer',
        ),
        migrations.AlterField(
            model_name='Car',
            name='manufacturer',
            field=models.ForeignKey(
                to='appName.Manufacturer', on_delete=models.CASCADE),
        ),
    ]
# Note: Change appName to your app name consisting the models
```
Once you create and save this migration file, you can now access the related model. Remember, we are not running migrations on database!
The trick here is that, we are just letting the Django know about the Models relations but in reality it does not exist.


There might be multiple ways of achieving the result, but rest assure, I have tried this on production as well.

I hope this will be useful!