2012-09-18 24 views
17

Tôi đã thêm trường UUID vào một số kiểu máy của tôi và sau đó được di chuyển với miền Nam. Bất kỳ đối tượng mới nào tôi tạo đều có trường UUID được điền chính xác. Tuy nhiên, các trường UUID trên tất cả các dữ liệu cũ hơn của tôi là null.Trường UUID được thêm sau khi dữ liệu đã có trong cơ sở dữ liệu. Có cách nào để điền vào trường UUID cho dữ liệu hiện có không?

Có cách nào để điền dữ liệu UUID cho dữ liệu hiện có không?

Trả lời

19

Đối với lớp mẫu sau:

from django_extensions.db.fields import UUIDField 

def MyClass: 
    uuid = UUIDField(editable=False, blank=True) 
    name = models.CharField() 

Nếu bạn đang sử dụng miền Nam, tạo ra một di chuyển dữ liệu:

python ./manage.py datamigration <appname> --auto 

Và sau đó sử dụng đoạn mã sau để cập nhật sự di cư với logic cụ thể để thêm UUID:

from django_extensions.utils import uuid 

def forwards(self, orm): 
    for item in orm['mypp.myclass'].objects.all(): 
     if not item.uuid: 
      item.uuid = uuid.uuid4() #creates a random GUID 
      item.save() 


def backwards(self, orm): 
    for item in orm['mypp.myclass'].objects.all(): 
     if item.uuid: 
      item.uuid = None 
      item.save() 

Bạn có thể tạo các loại UUID khác nhau, mỗi loại được tạo ra khác nhau ntly. uuid.py module in Django-extensions có danh sách đầy đủ các loại UUID bạn có thể tạo. Điều quan trọng cần lưu ý là nếu bạn chạy di chuyển này trong một môi trường có nhiều đối tượng, nó có khả năng hết thời gian (ví dụ, nếu sử dụng vải để triển khai). Lưu ý: Một phương pháp thay thế điền vào các trường đã có sẽ được yêu cầu cho môi trường sản xuất.

Có thể hết bộ nhớ trong khi cố gắng thực hiện việc này với số lượng lớn đối tượng (chúng tôi thấy mình thiếu bộ nhớ và không triển khai được 17.000 đối tượng).

Để giải quyết vấn đề này, bạn need to create a custom iterator trong quá trình di chuyển của bạn (hoặc dán nó ở nơi nó thực sự hữu ích và tham khảo nó khi bạn di chuyển). Nó sẽ giống như thế này:

def queryset_iterator(queryset, chunksize=1000): 
    import gc 
    pk = 0 
    last_pk = queryset.order_by('-pk')[0].pk 
    queryset=queryset.order_by('pk') 
    if queryset.count() < 1 
     return [] 
    while pk < last_pk: 
     for row in queryset.filter(pk__gt=pk)[:chunksize]: 
      pk = row.pk 
      yield row 
     gc.collect() 

Và sau đó di cư của bạn sẽ thay đổi để giống như thế này:

class Migration(DataMigration): 

    def forwards(self, orm): 
     for item in queryset_iterator(orm['myapp.myclass'].objects.all()): 
      if not item.uuid: 
       item.uuid = uuid.uuid1() 
       item.save() 

    def backwards(self, orm): 
     for item in queryset_iterator(orm['myapp.myclass'].objects.all()): 
      if item.uuid: 
       item.uuid = None 
       item.save() 
+4

Mặc dù các trình gỡ xuống không thể thấy điều này; Tôi sẽ nói nó: Nếu bạn đã downvoted tôi vì tôi đã cung cấp một tiền thưởng và sau đó trả lời câu hỏi, được thông báo rằng tôi không thể nhận được tiền thưởng của tôi trở lại anyway, vì vậy tôi không trả lời các câu hỏi cho tiền thưởng. Tôi trả lời nó bởi vì một thời gian sau khi tôi đặt ra tiền thưởng, tôi đã phải làm điều đó anyway, vì vậy tôi nghĩ rằng tôi muốn chia sẻ với tất cả mọi người như thế nào tôi đã làm nó. –

+0

Xin chào George, cá nhân tôi đã bỏ phiếu vì lý do đó, nhưng tôi mới để ngăn xếp và không biết bạn không thể lấy lại tiền thưởng của riêng bạn. Tôi đã lấy lại downvote của tôi và sau khi nhìn vào hồ sơ của bạn có thể thấy bạn là một thành viên cam kết, thông minh và hữu ích của stack :) –

6

Để thêm giá trị UUID cho tất cả các bản ghi hiện có đầu tiên bạn sẽ cần phải chắc chắn rằng mô hình của bạn có UUID được gửi với blank=True, null=True

Sau đó, chạy lệnh schemamigration bằng nam và sau đó mở tệp di chuyển kết quả. Và sau đó Chỉnh sửa tập tin chuyển đổi của bạn với những điều sau như trong này Trích post

:

Bạn sẽ cần phải nhập uuid nhập khẩu sau

Vào cuối của chuyển tiếp() chức năng thêm chuyển tiếp def sau (tự, orm):

... 
for a in MyModel.objects.all(): 
    a.uuid = u'' + str(uuid.uuid1().hex) 
    a.save() 

Như đã trình bày rằng sẽ lặp throu gh hiện tại các trường hợp và thêm một uuid vào nó như là một phần của di chuyển.

Các vấn đề liên quan