Explore Django's built-in migration system to manage database schema changes seamlessly. This project walks through creating models, generating migrations, adding fields, creating new models, and using Django's ORM to interact with migrated data - perfect for understanding Django's approach to schema evolution.
This walkthrough demonstrates creating models, applying migrations, adding fields, creating new models, and basic data operations using Django's ORM.
The example demonstrates how to:
django_migrations_example/
├── django_migrations_example/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── data_app/
│ ├── migrations/
│ │ ├── __init__.py
│ │ ├── 0001_initial.py
│ │ ├── 0002_rawdata_data_quality.py
│ │ └── 0003_processeddata.py
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
└── manage.py
from django.db import models class DataSource(models.Model): name = models.CharField(max_length=100) url = models.URLField(max_length=500) type = models.CharField(max_length=50) def __str__(self): return self.name class RawData(models.Model): source = models.ForeignKey(DataSource, on_delete=models.CASCADE) timestamp = models.DateTimeField() content = models.TextField() data_quality = models.FloatField(null=True) def __str__(self): return f"Data from {self.source.name} at {self.timestamp}" class ProcessedData(models.Model): raw_data = models.ForeignKey(RawData, on_delete=models.CASCADE) processed_content = models.TextField() processing_timestamp = models.DateTimeField(auto_now_add=True) def __str__(self): return f"Processed data for {self.raw_data}"
This file defines three models: DataSource, RawData, and ProcessedData, representing a basic data processing system.
Here's a step-by-step guide to set up and run the Django Migrations example:
Set up a new Django project:
pip install django
django-admin startproject django_migrations_example
cd django_migrations_example
Create a new app:
python manage.py startapp data_app
Add 'data_app' to INSTALLED_APPS in django_migrations_example/settings.py:
INSTALLED_APPS = [ # ... 'data_app', ]
Create data_app/models.py with the content:
from django.db import models class DataSource(models.Model): name = models.CharField(max_length=100) url = models.URLField(max_length=500) type = models.CharField(max_length=50) def __str__(self): return self.name class RawData(models.Model): source = models.ForeignKey(DataSource, on_delete=models.CASCADE) timestamp = models.DateTimeField() content = models.TextField() def __str__(self): return f"Data from {self.source.name} at {self.timestamp}"
Create and apply the initial migrations:
python manage.py makemigrations
python manage.py migrate
Add a new field to RawData in data_app/models.py:
class RawData(models.Model): # ... existing fields ... data_quality = models.FloatField(null=True)
Create and apply the new migration:
python manage.py makemigrations
python manage.py migrate
Add a new model to data_app/models.py:
class ProcessedData(models.Model): raw_data = models.ForeignKey(RawData, on_delete=models.CASCADE) processed_content = models.TextField() processing_timestamp = models.DateTimeField(auto_now_add=True) def __str__(self): return f"Processed data for {self.raw_data}"
Create and apply the migration for the new model:
python manage.py makemigrations
python manage.py migrate
To see the SQL that Django would run for these migrations:
python manage.py sqlmigrate data_app 0001_initial
python manage.py sqlmigrate data_app 0002_rawdata_data_quality
python manage.py sqlmigrate data_app 0003_processeddata
To view migration history:
python manage.py showmigrations
To use the models in Django shell:
python manage.py shell
# In the shell:
from data_app.models import DataSource, RawData, ProcessedData
from django.utils import timezone
# Create a DataSource
source = DataSource.objects.create(name="Example Source", url="https://example.com", type="API")
# Create a RawData instance
raw_data = RawData.objects.create(source=source, timestamp=timezone.now(), content="Sample raw data", data_quality=0.95)
# Create a ProcessedData instance
processed_data = ProcessedData.objects.create(raw_data=raw_data, processed_content="Processed: Sample raw data")
# Query the data
print(DataSource.objects.all())
print(RawData.objects.all())
print(ProcessedData.objects.all())
This example showcases how Django's migration system can manage database schema changes over time, allowing for version control of your database structure and smooth collaboration in team environments. It integrates seamlessly with Django's ORM, making it easy to define and evolve your data models as your project grows.