Cách An Toàn Chuyển Nhánh Git Với Django Migrations
Nếu bạn đã từng làm việc trên một dự án Django với nhiều nhánh tính năng, bạn có thể đã gặp phải tình huống khó chịu này: bạn chuyển nhánh và thấy rằng lược đồ cơ sở dữ liệu không đồng bộ, gây ra lỗi thời gian chạy hoặc xung đột migration. Giải pháp nhanh chóng là xóa toàn bộ cơ sở dữ liệu của bạn, nhưng có một cách tốt hơn.
Vấn Đề: Sự Trôi Dạt Của Lược Đồ Cơ Sở Dữ Liệu
Khi bạn làm việc với các nhánh Git khác nhau, mỗi nhánh có các migration riêng, cơ sở dữ liệu của bạn có thể nhanh chóng trở nên không khớp với mã nguồn của bạn. Xem xét quy trình công việc phổ biến sau:
- Bạn đang làm việc trên
feature-branch-avới các migration đến0004. - Bạn cần chuyển sang
feature-branch-b, có các migration đến0003. - Sau khi chuyển nhánh, cơ sở dữ liệu của bạn mong đợi migration
0004, nhưng mã của bạn chỉ có đến0003.
Kết quả? Django sẽ thông báo về các migration bị thiếu hoặc các migration đã được áp dụng nhưng không tồn tại trong nhánh hiện tại.
❌ Giải Pháp Nhanh (Nhưng Nguy Hiểm)
Nhiều nhà phát triển chọn phương án hủy diệt:
bash
python manage.py migrate your_app zero
python manage.py migrate
Điều này xóa toàn bộ dữ liệu của bạn và xây dựng lại lược đồ từ đầu. Mặc dù nó hoạt động, nhưng bạn sẽ mất tất cả dữ liệu phát triển của mình, điều này đặc biệt đau đớn nếu bạn đã dành thời gian thiết lập dữ liệu thử nghiệm hoặc có những bản ghi quan trọng trong quá trình phát triển.
⚙️ Giải Pháp Đúng: Quay Lại Trước Khi Chuyển Nhánh
Để có một phương pháp kiểm soát hơn mà không mất dữ liệu, hãy đảo ngược các migration từ nhánh hiện tại của bạn trước khi chuyển sang nhánh mới. Điều này giúp lược đồ cơ sở dữ liệu của bạn đồng bộ với mã của bạn.
Quy Trình Bước-Đến-Bước
- Tìm migration chung cuối cùng mà cả hai nhánh đều chia sẻ:
bash
python manage.py showmigrations
Điều này cho bạn biết các migration đã được áp dụng và giúp xác định nơi các nhánh phân chia.
- Di chuyển cơ sở dữ liệu của bạn trở về trạng thái chung đó: Nếu migration chung là
0002:
bash
python manage.py migrate your_app_name 0002
- Chuyển đến nhánh mục tiêu của bạn:
bash
git checkout target-branch-name
- Áp dụng các migration của nhánh mới:
bash
python manage.py migrate
Phương pháp này tuy thủ công hơn nhưng bảo tồn dữ liệu của bạn và tuân theo quy trình đúng để áp dụng và hủy bỏ các migration.
🚀 Thêm: Aliases Makefile Để Quản Lý Migration Dễ Dàng
Để làm cho quy trình này mượt mà hơn, tôi đã tạo ra các alias Makefile tự động tìm và quay lại migration mới nhất từ nhánh mục tiêu. Những alias này đặc biệt hữu ích trong các môi trường khác nhau:
makefile
staging-rollback:
@echo "Tìm tệp migration mới nhất..."
@MIGRATION_FILE=$$(git ls-tree -r --name-only origin/develop -- **/migrations/*.py | grep -E '[0-9]{4}_.*\.py' | sort -n -t'/' -k3 | tail -1) && \
APP_NAME=$$(echo "$$MIGRATION_FILE" | cut -d'/' -f1) && \
MIGRATION_NAME=$$(basename "$$MIGRATION_FILE" .py) && \
echo "Quay lại migration $$MIGRATION_NAME trong ứng dụng $$APP_NAME..." && \
docker compose exec web python manage.py migrate $$APP_NAME $$MIGRATION_NAME
dev-rollback:
@echo "Tìm tệp migration mới nhất..."
@MIGRATION_FILE=$$(git ls-tree -r --name-only origin/develop -- **/migrations/*.py | grep -E '[0-9]{4}_.*\.py' | sort -n -t'/' -k3 | tail -1) && \
APP_NAME=$$(echo "$$MIGRATION_FILE" | cut -d'/' -f1) && \
MIGRATION_NAME=$$(basename "$$MIGRATION_FILE" .py) && \
echo "Quay lại migration $$MIGRATION_NAME trong ứng dụng $$APP_NAME..." && \
docker compose exec web-dev python manage.py migrate $$APP_NAME $$MIGRATION_NAME
local-rollback:
@echo "Tìm tệp migration mới nhất..."
@MIGRATION_FILE=$$(git ls-tree -r --name-only origin/develop -- **/migrations/*.py | grep -E '[0-9]{4}_.*\.py' | sort -n -t'/' -k3 | tail -1) && \
APP_NAME=$$(echo "$$MIGRATION_FILE" | cut -d'/' -f1) && \
MIGRATION_NAME=$$(basename "$$MIGRATION_FILE" .py) && \
echo "Quay lại migration $$MIGRATION_NAME trong ứng dụng $$APP_NAME..." && \
python manage.py migrate $$APP_NAME $$MIGRATION_NAME
Các lệnh này tự động:
- Tìm tệp migration mới nhất từ nhánh phát triển (hoặc bất kỳ nhánh mục tiêu nào bạn chỉ định)
- Trích xuất tên ứng dụng và số migration
- Thực thi lệnh migrate phù hợp để quay lại migration cụ thể đó
Ví Dụ Sử Dụng
bash
# Quay lại cơ sở dữ liệu cục bộ của bạn để khớp với nhánh phát triển
make local-rollback
# Quay lại môi trường phát triển của bạn
make dev-rollback
# Quay lại staging để chuẩn bị cho một lần triển khai
make staging-rollback
💡 Mẹo Chuyên Nghiệp cho Quản Lý Migration
- Cam kết thường xuyên: Các migration nhỏ, tập trung dễ quản lý hơn so với các migration lớn, phức tạp.
- Sử dụng tên migration có ý nghĩa: Điều này giúp xác định những gì mỗi migration thực hiện khi bạn cần quay lại.
- Giữ đồng bộ các migration: Cố gắng tránh có xung đột migration giữa các nhánh.
- Kiểm tra việc quay lại migration: Đảm bảo rằng các migration của bạn có thể bị đảo ngược mà không mất dữ liệu.
Kết Luận
Chuyển nhánh không nhất thiết có nghĩa là mất dữ liệu phát triển của bạn. Bằng cách quản lý các migration một cách hợp lý và sử dụng các công cụ tự động như các alias Makefile này, bạn có thể duy trì một quy trình làm việc mượt mà giữa nhiều nhánh tính năng khác nhau. Những giây phút bổ sung dành cho việc quay lại các migration đúng cách sẽ tiết kiệm cho bạn hàng giờ khôi phục dữ liệu bị mất.
Chiến lược migration nào đã hoạt động tốt cho nhóm của bạn? Hãy chia sẻ mẹo của bạn trong phần bình luận dưới đây!
Theo dõi để nhận thêm mẹo về Django và quy trình phát triển!