Cách tiếp cận được đề xuất để đặt lại lịch sử di chuyển bằng Django South là gì?


153

Tôi đã tích lũy được khá nhiều lần di chuyển bằng Nam (0,7) và Django (1.1.2) đang bắt đầu tiêu tốn khá nhiều thời gian trong các bài kiểm tra đơn vị của tôi. Tôi muốn đặt lại đường cơ sở và bắt đầu một bộ di chuyển mới. Tôi đã xem lại tài liệu hướng Nam , thực hiện tìm kiếm Google / Stackoverflow thông thường (ví dụ: "django phía nam (đặt lại HOẶC xóa HOẶC xóa) lịch sử di chuyển") và không tìm thấy điều gì rõ ràng.

Một cách tiếp cận tôi đã dự tính sẽ bao gồm "bắt đầu lại" bằng cách "xóa" Nam hoặc "xóa" lịch sử theo cách thủ công (ví dụ: xóa bảng db, xóa tệp di chuyển khỏi giám đốc di chuyển) và chỉ chạy lại,

./manage.py schemamigration southtut --initial

Vì vậy, nếu bất cứ ai đã làm điều này trước đây và có một số lời khuyên / đề xuất, họ sẽ được đánh giá rất cao.


đôi khi bạn cần thêm thủ công __init__.pyvàoappname/migrations
laike9m

2
Làm cách nào để bạn đặt lại di chuyển trong 1.7 (với di chuyển tích hợp)?
Timo

1
@Timo: docs.djangoproject.com/en/dev/topics/migations/ Khăn có thể là một cách tiếp cận. Bạn cũng có thể xóa di chuyển / thư mục của mình và phát hành ./manage.py makemigrationslại nhưng điều tồi tệ sẽ xảy ra nếu bạn không bắt đầu từ một db mới ...
Jocelyn delalande 17/12/14

Tôi nghĩ squashmigrationslà câu trả lời đúng
Julio Marins

Câu trả lời:


121

EDIT - Tôi đang đặt một bình luận bên dưới ở đầu bài này vì điều quan trọng là phải đọc nó trước câu trả lời> được chấp nhận sau @andybak

@Dominique: Lời khuyên của bạn về việc quản lý cài đặt lại phía nam rất nguy hiểm và có thể phá hủy cơ sở dữ liệu nếu có bất kỳ ứng dụng bên thứ ba nào sử dụng phía nam trong dự án, như được chỉ ra bởi @thnee bên dưới. Vì câu trả lời của bạn có rất nhiều câu hỏi, tôi thực sự đánh giá cao nếu bạn có thể chỉnh sửa nó và thêm ít nhất một cảnh báo về điều này, hoặc (thậm chí tốt hơn) thay đổi nó để phản ánh cách tiếp cận @hobs (cũng thuận tiện, nhưng không ảnh hưởng đến các ứng dụng khác) - cảm ơn! - chrisv ngày 26 tháng 3 năm 13 lúc 9:09

Câu trả lời được chấp nhận sau đây:

Đầu tiên, một câu trả lời của tác giả miền Nam :

Miễn là bạn cẩn thận thực hiện đồng thời trên tất cả các triển khai, không nên có bất kỳ vấn đề nào với việc này. Cá nhân, tôi sẽ làm:

    rm -r appname/migrations/ 
    ./manage.py reset south 
    ./manage.py convert_to_south appname 

(Lưu ý rằng reset southphần của LỪA xóa các bản ghi di chuyển cho TẤT CẢ các ứng dụng, vì vậy hãy đảm bảo bạn chạy hai dòng khác cho tất cả các ứng dụng hoặc xóa có chọn lọc).

Cuộc convert_to_southgọi ở cuối tạo ra một di chuyển mới và giả mạo áp dụng nó (vì cơ sở dữ liệu của bạn đã có các bảng tương ứng). Không cần phải bỏ tất cả các bảng ứng dụng trong suốt quá trình.

Đây là những gì tôi đang làm trên máy chủ dev + sản ​​xuất của mình khi tôi cần loại bỏ tất cả các chuyển đổi dev không cần thiết này:

  1. Hãy chắc chắn rằng chúng ta có cùng một lược đồ DB ở cả hai bên
  2. xóa mọi thư mục di chuyển ở cả hai bên
  3. chạy ./manage.py đặt lại phía nam (như bài đăng đã nói) ở cả hai bên = xóa bảng phía nam *
  4. chạy ./manage.py convert_to_south ở cả hai bên (giả mạo di chuyển 0001)
  5. sau đó tôi có thể bắt đầu lại để thực hiện di chuyển và đẩy các thư mục di chuyển trên máy chủ của mình

* ngoại trừ nếu bạn chỉ muốn xóa một ứng dụng trong số những ứng dụng khác, nếu vậy bạn sẽ cần chỉnh sửa bảng south_history của mình và chỉ xóa các mục về ứng dụng của bạn.


2
Chỉ để ghi lại, phản hồi của tác giả miền Nam như sau: Miễn là bạn cẩn thận thực hiện nó trên tất cả các triển khai đồng thời, không nên có bất kỳ vấn đề nào với việc này. Cá nhân, tôi sẽ làm: rm -r appname / di chuyển / ./manage.py đặt lại về phía nam ./manage.py convert_to_south tên ứng dụng hai dòng khác cho tất cả các ứng dụng hoặc xóa chọn lọc).
Adriaan Tijsseling

2
Cũng lưu ý rằng nếu bạn bỏ các bảng, thì bạn cần manage.py schemamigration app name --initialthay vì convert_to_south.
Adriaan Tijsseling

7
Kể từ Django 1.5, lệnh quản lý "thiết lập lại" không còn nữa. Thay vào đó, bạn sẽ muốn làm một cái gì đó đại khái như south.models.MigrationHistory.objects.all().delete().
Andrew B.

13
@Dominique: lời khuyên của bạn về manage.py reset southnguy hiểmcó thể phá hủy các cơ sở dữ liệu nếu có bất kỳ ứng dụng của bên thứ ba sử dụng nam trong dự án, như ra nhọn bởi @thnee dưới đây. Vì câu trả lời của bạn có rất nhiều câu hỏi, tôi thực sự đánh giá cao nó nếu bạn có thể chỉnh sửa nó và thêm ít nhất một cảnh báo về điều này, hoặc (thậm chí tốt hơn) thay đổi nó để phản ánh cách tiếp cận @hobs (cũng thuận tiện, nhưng không ảnh hưởng đến các ứng dụng khác) - cảm ơn!
chrisv

3
Tại sao điều này rất được nâng cao? Bạn gần như KHÔNG BAO GIỜ xóa hoàn toàn bảng south_migrationhistory của mình. Điều đó sẽ hoàn toàn làm hỏng bất kỳ ứng dụng phụ thuộc nào với việc di chuyển mà bạn không muốn chạm vào. Câu trả lời của Hob là đúng.
Cerin

188

Nếu bạn cần chọn lọc (chỉ một ứng dụng), hãy thiết lập lại quá trình di chuyển mất quá nhiều thời gian, điều này có hiệu quả với tôi.

rm <app-dir>/migrations/*
python manage.py schemamigration <app-name> --initial
python manage.py migrate <app-name> 0001 --fake  --delete-ghost-migrations

Đừng quên khôi phục thủ công bất kỳ phụ thuộc nào trên các ứng dụng khác bằng cách thêm các dòng như depends_on = (("<other_app_name>", "0001_initial"),("<yet_another_app_name>", "0001_initial"))vào <app-dir>/migrations/0001_initial.pytệp của bạn , làm thuộc tính đầu tiên trong lớp di chuyển của bạn ngay bên dưới class Migration(SchemaMigration):.

Sau đó, bạn có thể ./manage.py migrate <app-name> --fake --delete-ghost-migrationstrên các môi trường khác, theo câu trả lời SO này . Tất nhiên, nếu bạn giả mạo xóa hoặc giả, migrate zerobạn sẽ cần xóa thủ công mọi bảng db còn sót lại bằng cách di chuyển như thế này .

Một tùy chọn hạt nhân hơn là ./manage.py migrate --fake --delete-ghost-migrationstrên máy chủ triển khai trực tiếp theo sau là một khối vuông [của tôi]. Sau đó, đường ống đổ vào [my] sql trên các môi trường nơi bạn cần db di chuyển, được điền đầy đủ. Nam biết, tôi biết, nhưng làm việc cho tôi.


2
Điều tôi thực sự muốn là "lấy mô hình từ làm phúc âm và làm cho tôi sạch từ thời điểm đó trở đi". Do đó, giữ lại khả năng thiết lập một triển khai từ đầu hoặc làm việc từ một triển khai hiện có.
Bryce

1
Đó là những gì nó làm.
hobs

2
@hobs Tôi đã nhận được một DependsOnUnknownMigrationthời gian giả mạo di chuyển ban đầu mới. Nhờ bình luận của bạn, tôi có thể nhận ra rằng tôi nên cập nhật depends_ontuyên bố bất cứ nơi nào nó đề cập đến ứng dụng này. Đây thực sự là câu trả lời tốt nhất ở đây. Cảm ơn! :)
manu

55

Nhờ những câu trả lời của Dominique Guardiola và hobs, nó đã giúp tôi giải quyết một vấn đề khó khăn. Tuy nhiên, có một vài vấn đề với giải pháp, đây là vấn đề của tôi.

Sử dụng manage.py reset southkhông phải là một ý tưởng tốt nếu bạn có bất kỳ ứng dụng của bên thứ ba sử dụng miền Nam, ví dụ django-cms(về cơ bản tất cả mọi thứ sử dụng miền Nam).

reset south sẽ xóa tất cả lịch sử di chuyển cho tất cả các ứng dụng mà bạn đã cài đặt.

Bây giờ hãy xem xét rằng bạn nâng cấp lên phiên bản mới nhất django-cms, nó sẽ chứa các chuyển đổi mới như thế nào 0009_do_something.py. Nam chắc chắn sẽ bị nhầm lẫn khi bạn cố gắng chạy di cư đó mà không cần phải 0001thông qua 0008trong lịch sử di cư.

Sẽ tốt hơn / an toàn hơn khi chỉ chọn lại các ứng dụng mà bạn đang duy trì .


Trước hết, hãy đảm bảo rằng các ứng dụng của bạn không có bất kỳ sự không đồng bộ nào giữa các lần di chuyển trên đĩa và việc di chuyển đã được thực hiện trên cơ sở dữ liệu. Nếu không sẽ đau đầu.

1. Xóa lịch sử di chuyển cho các ứng dụng của tôi

sql> delete from south_migrationhistory where app_name = 'my_app';

2. Xóa di chuyển cho các ứng dụng của tôi

$ rm -rf my_app/migrations/

3. Tạo di chuyển ban đầu mới cho ứng dụng của tôi

$ ./manage.py schemamigration --initial my_app

4. Fake thực hiện di chuyển ban đầu cho các ứng dụng của tôi

Điều này chèn các di chuyển vào south_migrationhistorymà không chạm vào các bảng thực tế:

$ ./manage.py migrate --fake my_app

Bước 3 và 4 thực sự chỉ là một biến thể dài hơn manage.py convert_to_south my_app, nhưng tôi thích điều khiển thêm đó, trong tình huống tế nhị như sửa đổi cơ sở dữ liệu sản xuất.


2
Tôi đã chỉnh sửa câu trả lời của mình để kết hợp các bản sửa lỗi cho các vấn đề bạn tìm thấy (chỉ cần đoán chúng dựa trên câu trả lời của bạn) và kiểm tra nó trên cơ sở dữ liệu sản xuất với hàng triệu hàng.
hobs

2
Đây là khá nhiều những gì chúng ta đang làm. Nếu bạn sử dụng tùy chọn --delete-ghost-Migration ở bước 4, bạn có thể bỏ qua bước 1.
tobych

Bạn nên chỉ định rõ ràng tên ứng dụng ./manage.py migrate --fakenếu bạn không muốn giả mạo di chuyển các ứng dụng khác đang chờ di chuyển.
wadim

2
@wadim Do đó bước 0: "đảm bảo rằng bạn không có sự không đồng bộ giữa các lần di chuyển trên đĩa và di chuyển đã được thực hiện trên cơ sở dữ liệu".
thnee

@thnee Phải. Có lẽ đáng nói đến là bạn đang tham khảo tất cả các ứng dụng đã cài đặt ở bước 0. Bạn có biết cách dễ dàng để thực hiện bước 0 không?
wadim

7

Giống như thnee (xem câu trả lời của cô ấy), chúng tôi đang sử dụng cách tiếp cận nhẹ nhàng hơn với đề xuất của tác giả miền Nam (Andrew Godwin) được trích dẫn ở nơi khác ở đây và chúng tôi tách biệt những gì chúng tôi làm với cơ sở mã từ những gì chúng tôi làm với cơ sở dữ liệu, trong khi triển khai , bởi vì chúng tôi cần các triển khai có thể lặp lại:

Những gì chúng tôi làm trong mã:

# Remove all the migrations from the app
$ rm -fR appname/migrations
# Make the first migration (don't touch the database)
$ ./manage.py schemamigration appname --initial

Chúng ta sẽ làm gì với cơ sở dữ liệu khi mã đó được triển khai

# Fake the migration history, wiping out the rest
$ ./manage.py migrate appname --fake --delete-ghost-migrations

Tôi nghĩ rằng tôi chỉ làm điều tương tự, nhưng xóa thủ công các mục cơ sở dữ liệu, thay vì sử dụng --delete_ghoist-di chuyển. Cách của bạn đẹp hơn một chút.
wobbily_col

1

Nếu bạn chỉ làm việc trên máy dev, tôi đã viết một lệnh quản lý thực hiện khá nhiều những gì Dominique đề xuất.

http://balzerg.blogspot.co.il/2012/09/django-app-reset-with-south.html

Ngược lại với đề xuất của tác giả phía nam, điều này sẽ KHÔNG HẠI các ứng dụng được cài đặt khác sử dụng phía nam.


Và nếu, không giống như tác giả, bạn muốn giữ các di chuyển hiện có (nghĩa là bạn muốn đặt lại ứng dụng cũng như lịch sử di chuyển, nhưng vẫn giữ các di chuyển thực tế), thì bạn có thể thử điều này: goo.gl/0ZnWm
mgasms

1

Sau đây chỉ khi bạn muốn đặt lại tất cả các ứng dụng. Vui lòng sao lưu tất cả các cơ sở dữ liệu của bạn trước khi làm việc. Ngoài ra, hãy ghi lại tệp phụ thuộc của bạn trong các tệp ban đầu nếu có.

Cho một lần:

(1) find . -type d -name migrations -exec git rm -rf '{}' \;
(2) find . -type d -name migrations -exec rm -rf '{}' \;
(3) ./manage.py schemamigration <APP_NAME> --initial
(4) [GIT COMMIT]

Kiểm tra bootstrapping dự án của bạn trước khi đẩy. Sau đó, đối với mỗi máy cục bộ / từ xa, áp dụng như sau:

(5) [GIT PULL]
(6) ./manage.py reset south
(7) ./manage.py migrate --fake

Làm ban đầu (3) cho mỗi ứng dụng bạn muốn tham gia lại. Lưu ý rằng, đặt lại (6) sẽ chỉ xóa lịch sử di chuyển, do đó không gây hại cho thư viện. Di chuyển giả (7) sẽ đưa lại lịch sử di chuyển của bất kỳ ứng dụng bên thứ 3 nào được cài đặt.


0

xóa tập tin cần thiết khỏi thư mục ứng dụng

đường dẫn cá thể

 cd /usr/local/lib/python2.7/dist-packages/wiki/south_migrations

wiki - là ứng dụng của tôi

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.