Di chuyển Django - Tính năng BẮT BUỘC phải biết
By hientd, at: 09:31 Ngày 07 tháng 8 năm 2023
Thời gian đọc ước tính: __READING_TIME__ minutes


Chào mừng đến với thế giới của Django migrations, nơi quá trình phát triển lược đồ cơ sở dữ liệu trở nên tự động và dễ dàng. Cho dù bạn mới bắt đầu hay hướng đến sự thành thạo, bài viết này sẽ hướng dẫn bạn qua các giai đoạn khác nhau của Django migrations, từ đơn giản đến phức tạp. Hãy cùng tìm hiểu các mẹo, thủ thuật và những thực tiễn tốt nhất sẽ giúp bạn khai thác hết tiềm năng của Django migrations.
Một chủ đề hữu ích khác mà chúng tôi đề cập là ở đây
Hiểu về Django Migrations
Trong lĩnh vực phát triển web, việc duy trì tính nhất quán của lược đồ cơ sở dữ liệu của bạn là rất quan trọng. Django migrations là một bộ công cụ cho phép bạn đạt được điều này một cách liền mạch - đây là một tính năng tích hợp sẵn kể từ Django 1.7. Trước đây, Django-South là gói chính được sử dụng cho migrations.
Những migrations này cho phép bạn thực hiện các thay đổi đối với các model của bạn – các lớp Python định nghĩa cấu trúc cơ sở dữ liệu của bạn – và tự động áp dụng những thay đổi này vào cơ sở dữ liệu, đảm bảo lược đồ của nó phát triển cùng với codebase của bạn. Điều này đặc biệt quan trọng khi ứng dụng của bạn phát triển và tiến hóa theo thời gian.
Quá trình migration về cơ bản là câu trả lời của Django cho câu hỏi: "Làm thế nào chúng ta có thể giữ cho lược đồ cơ sở dữ liệu của mình đồng bộ với các thay đổi code của chúng ta?" Tự động hóa này giúp các nhà phát triển tiết kiệm hàng giờ làm việc mà nếu không sẽ phải dành ra để sửa đổi lược đồ cơ sở dữ liệu bằng tay.
Giai đoạn dễ dàng: Bắt đầu với Migrations
Bắt đầu hành trình migration của bạn thật dễ dàng như tạo một dự án và ứng dụng Django mới. Sau khi bạn đã định nghĩa các model của mình trong một ứng dụng, Django giúp bạn tạo ra migration ban đầu – một ảnh chụp nhanh về các model hiện tại của bạn. Việc chạy lệnh python manage.py makemigrations
sẽ biên dịch ảnh chụp nhanh này thành một script migration. Sau đó, lệnh python manage.py migrate
sẽ áp dụng những migrations này vào cơ sở dữ liệu của bạn.
Ví dụ, hãy tưởng tượng tạo một ứng dụng blog đơn giản. Bạn định nghĩa một model Post
với các trường như title
, content
và publish_date
. Chỉ với một vài lệnh đơn giản, Django sẽ ghi lại những thay đổi này và kết hợp chúng vào lược đồ cơ sở dữ liệu của bạn.
# models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
publish_date = models.DateTimeField()
def __str__(self):
return self.title
Điều hướng qua các tình huống phổ biến
Khi bạn đi sâu hơn vào thế giới của migrations, bạn sẽ gặp phải nhiều tình huống đòi hỏi phải sửa đổi lược đồ. Thêm các trường mới, thay đổi thuộc tính của các trường hiện có, xóa các trường lỗi thời – tất cả những điều này đều là một phần của trò chơi.
Giả sử bạn quyết định nâng cao model Post
của mình bằng cách thêm trường category
. Việc thêm này yêu cầu tạo một migration mới để phản ánh sự thay đổi trong lược đồ cơ sở dữ liệu của bạn. Tương tự, nếu bạn muốn đổi tên trường hoặc sửa đổi thuộc tính của nó, migrations sẽ xử lý điều này một cách liền mạch.
Model Post ban đầu là
# models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
publish_date = models.DateTimeField()
name = models.CharField(max_length=200) # một trường trùng lặp với title
def __str__(self):
return self.title
Ví dụ: Thêm trường mới hoặc Xóa trường
# models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
publish_date = models.DateTimeField()
category = models.CharField(max_length=100) # Thêm trường category và xóa trường name
def __str__(self):
return self.title
Để tạo file migration, chúng ta cần chạy
python manage.py makemigrations
python manage.py migrate
Xử lý Data Migrations
Migrations không chỉ dừng lại ở việc sửa đổi lược đồ. Chúng cũng bao gồm data migrations, đảm bảo dữ liệu của bạn vẫn còn nguyên vẹn ngay cả khi lược đồ của bạn phát triển. Khi bạn cần thao tác dữ liệu cùng với một thay đổi lược đồ, data migrations sẽ giúp bạn.
Hãy xem xét một kịch bản mà bạn đang thêm một trường mới, author
, vào model Post
của bạn. Trường này cần được điền dữ liệu, và một script data migration cho phép bạn thực hiện điều này trong khi áp dụng thay đổi lược đồ.
Ví dụ, nếu chuỗi "Conan Doyle" tồn tại trong nội dung Post, thì tác giả là "Connan Doyle". Script migration để cập nhật giá trị tác giả là
# Generated by Django A.B on YYYY-MM-DD HH:MM
from django.db import migrations
def update_author(apps, schema_editor):
Post = apps.get_model("blogapp", "Post")
known_authors = ["Conan Doyle", "Stephen King", "William Shakespeare"]
for post in Post.objects.all():
if known_author in post.content:
post.author = known_author
break
post.save(update_fields=["author"])
class Migration(migrations.Migration):
dependencies = [
("blogapp", "0004_add_author_field"),
]
operations = [
# bỏ qua reverse_code=... nếu bạn không muốn migration có thể đảo ngược.
migrations.RunPython(update_author, reverse_code=migrations.RunPython.noop),
]
Các thách thức và giải pháp phổ biến
Khi bạn tiến bộ, bạn sẽ phải đối mặt với những thách thức phức tạp hơn. Xử lý các mối quan hệ model, đổi tên model hoặc ứng dụng và xử lý các phụ thuộc tuần hoàn có vẻ khó khăn, nhưng Django migrations đã hỗ trợ bạn.
Hãy tưởng tượng bạn đã có một model Post với trường author
là một CharField
. Bây giờ chúng ta muốn tạo một model mới Author
để theo dõi tất cả các tác giả và sử dụng ForeignKey
trong model Post
.
Những gì chúng ta phải làm là:
1. Thay đổi tên trường từ author
thành author_name
sau đó chạy python manage.py makemigrations rồi python manage.py migrate
2. Thêm model mới Author
và author
ForeignKey
vào model Post
(null=True, blank=True
)
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
publish_date = models.DateTimeField()
category = models.CharField(max_length=100)
author = models.ForeignKey('Author', on_delete=models.CASCADE, related_name="posts", null=True, blank=True)
def __str__(self):
return self.title
3. Thêm migration mới để điền dữ liệu chính xác
# Trong file data migration của bạn (blogapp/migrations/xxxx_data_migration.py)
from django.db import migrations
def populate_authors(apps, schema_editor):
Post = apps.get_model('blogapp', 'Post')
Author = apps.get_model('blogapp', 'Author')
for post in Post.objects.all():
author, _ = Author.objects.get_or_create(name=post.author_name)
book.author = author
book.save()
class Migration(migrations.Migration):
dependencies = [
('blogapp', '0002_rename_author_field'),
]
operations = [
migrations.RunPython(populate_authors),
]
4. Xóa null=True, blank=True
trong trường author (model Post). Xóa trường author_name
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
publish_date = models.DateTimeField()
category = models.CharField(max_length=100)
author = models.ForeignKey('Author', on_delete=models.CASCADE, related_name="posts")
def __str__(self):
return self.title
Các kỹ thuật nâng cao và thực tiễn tốt nhất
Để thực sự thành thạo migrations, các kỹ thuật nâng cao sẽ được sử dụng.
Kiểm soát phiên bản trở nên vô cùng quý giá, cho phép bạn theo dõi các thay đổi đối với lịch sử migration của mình một cách hiệu quả.
Squashing migrations, bao gồm việc kết hợp nhiều migrations thành một, giúp duy trì lịch sử sạch hơn và dễ quản lý hơn.
Tối ưu hóa các truy vấn cơ sở dữ liệu trong migrations cũng là một kỹ năng đáng để trau dồi. Đảm bảo các truy vấn của bạn hiệu quả có thể ngăn ngừa các điểm nghẽn trong quá trình thực hiện migration.
Fake migration là một công cụ tuyệt vời để quản lý giải quyết sự không nhất quán giữa mã nguồn ứng dụng Django và thay đổi cơ sở dữ liệu. Vì nhiều nhóm đang làm việc trên cùng một cơ sở dữ liệu, một số nhóm có thể thay đổi lược đồ cơ sở dữ liệu và chúng ta cần đảm bảo rằng ứng dụng Django tuân theo.
Kiểm thử và khôi phục Migration
Kiểm thử migrations của bạn là rất quan trọng để ngăn ngừa các sự cố trong tương lai. Django cho phép bạn mô phỏng migrations trên một cơ sở dữ liệu thử nghiệm, đảm bảo mọi thứ hoạt động như mong đợi trước khi áp dụng các thay đổi vào môi trường sản xuất của bạn.
Trong trường hợp một migration thất bại hoặc dẫn đến những hậu quả không mong muốn, việc có một chiến lược khôi phục là rất cần thiết. Khung migration của Django cung cấp các công cụ để hoàn tác migrations và khôi phục cơ sở dữ liệu của bạn về trạng thái ổn định.
python manage.py migrate blogapp 0001
python manage.py migrate blogapp
python manage.py migrate blogapp 0003
Thành thạo Migrations: Hiệu suất và Tối ưu hóa
Đạt đến trình độ thành thạo không chỉ bao gồm việc hiểu các kiến thức cơ bản mà còn tối ưu hóa toàn bộ quá trình. Việc lập hồ sơ hiệu suất migration giúp xác định các lĩnh vực cần cải thiện. Chia các migration lớn thành các migration nhỏ hơn sẽ giảm thiểu rủi ro lỗi và cải thiện khả năng bảo trì.
Việc sử dụng hiệu quả các giao dịch cơ sở dữ liệu có thể tăng tốc đáng kể việc thực hiện migration, đặc biệt là đối với các tập dữ liệu lớn.
Một vấn đề nổi tiếng với Django migraiton là việc thêm index trong các bảng lớn rất chậm. Vì Django thêm index mà không có tùy chọn CONCURRENTLY. Để giải quyết điều này, chúng ta nên tự tạo CONCURRENTLY INDEX, sau đó migrate với tùy chọn fake
python manage.py migrate blogapp 0004 --fake
Kết luận
Từ việc khởi tạo migrations đơn giản đến việc thành thạo các kỹ thuật tối ưu hóa, hành trình này là một hành trình chuyển đổi. Django migrations không chỉ là một công cụ kỹ thuật; chúng là một khía cạnh quan trọng trong việc duy trì một codebase mạnh mẽ và luôn phát triển.
Vì vậy, hãy đón nhận những thách thức, thử nghiệm với các giải pháp và để Django migrations là người bạn đồng hành của bạn trong bối cảnh phát triển web luôn thay đổi.
Các gói hữu ích cho Cơ sở dữ liệu
Câu hỏi thường gặp
- Câu hỏi 1: Migrations có thể dẫn đến mất dữ liệu không?
- Đáp: Không, migrations được thiết kế để bảo toàn tính toàn vẹn dữ liệu trong quá trình thay đổi lược đồ.
- Câu hỏi 2: Làm thế nào tôi có thể xử lý các phụ thuộc tuần hoàn giữa các model trong migrations?
- Đáp: Bằng cách sử dụng hàm
apps.get_model
và sắp xếp cẩn thận các migrations.
- Đáp: Bằng cách sử dụng hàm
- Câu hỏi 3: Squashing migrations luôn cần thiết phải không?
- Đáp: Squashing có thể cải thiện tính rõ ràng của lịch sử migration của bạn, nhưng nó không bắt buộc.
- Câu hỏi 4: Migrations có thể đảo ngược được không?
- Đáp: Có, hầu hết các migrations đều có thể được đảo ngược bằng lệnh
migrate
.
- Đáp: Có, hầu hết các migrations đều có thể được đảo ngược bằng lệnh
Hãy nhớ rằng sự thành thạo cần thời gian, thực hành và sự sẵn lòng học hỏi từ những thách thức. Chúc bạn migration vui vẻ!