2012-04-03 32 views
8

Tôi sử dụng miền nam để di chuyển các mô hình django của mình. Tuy nhiên có một lỗi khó chịu ở phía nam. Nó không đặt giá trị mặc định trong Postgres Databases. Ví dụ:di chuyển về phía nam django, không đặt mặc định

created_at = models.DateTimeField(default = datetime.now) 
tag_id = models.PositiveIntegerField(default = 0) 

Miền Nam sẽ thêm 2 trường này vào cơ sở dữ liệu, nhưng không đặt giá trị mặc định, cần thực hiện thủ công.

Có bản vá nào cho lỗi này không?

CẬP NHẬT Tôi đã thử đặt ngày mặc định bằng auto_now_add=True nhưng điều đó cũng không đặt mặc định. Thêm null=True vào trường thêm db.alter_column trong tập lệnh di chuyển được tạo ra ở phía nam. Nhưng chỉ có loại bỏ ràng buộc NOT NULL, không thêm mặc định. Tương tự cho trường số nguyên

Trả lời

11

Đây không phải là lỗi, ở miền Nam hoặc nơi khác.

Tôi nghĩ bạn đang bối rối về cách các giá trị mặc định hoạt động trong Django nói chung. Django không đặt giá trị mặc định trong lược đồ cơ sở dữ liệu. Nó áp dụng chúng trực tiếp trong Python, khi một cá thể mới được tạo ra. Bạn có thể xác minh điều này bằng cách thực hiện manage.py sqlall và thấy rằng SQL được tạo không chứa thuộc tính default.

+2

Làm cách nào để thực thi mặc định trong cơ sở dữ liệu Postgres. Tôi có apis đàm phán trực tiếp với cơ sở dữ liệu được tạo ra bởi django. Họ hy vọng mặc định sẽ được đặt ra. – jerrymouse

+5

Bạn sẽ phải sử dụng SQL tùy chỉnh để tự sửa đổi lược đồ. Bạn có thể làm điều này trong miền Nam bằng cách chuyển SQL sang ['db.execute'] (http://south.aeracode.org/docs/databaseapi.html#db-execute). –

+3

Daniel chỉ vì Django cố gắng để ngăn chặn người dùng thay đổi mặc định trường ở cấp độ lược đồ, điều đó không có nghĩa là họ KHÔNG THỂ có thể. Tôi đã đăng một giải pháp thực tế dưới đây. – galarant

21

Nếu bạn đang tự động tạo ra sự di cư của bạn sử dụng:

./manage.py schemamigration app_name --auto 

Sau đó, bạn cần phải thực hiện một chỉnh sửa nhỏ để di cư trước khi bạn thực sự áp dụng nó. Đi vào sự di cư được tạo ra (nên được gọi là một cái gì đó giống như app_name/di cư/000X__auto_add_field_foo.py) và tìm kiếm các đối số:

keep_default=False 

trong cuộc gọi db.add_column. Chỉ cần thay đổi điều này thành:

keep_default=True 

Và Django bây giờ sẽ áp dụng giá trị mặc định của bạn cho giản đồ thực tế, ngoài bất kỳ hàng hiện có nào. Sẽ là tuyệt vời nếu South có một số loại thiết lập để tạo ra tham số này là True theo mặc định, nhưng không có may mắn như vậy. Bạn sẽ cần phải thực hiện chỉnh sửa này mỗi lần.

+0

+1 Dễ dàng hơn nhiều so với việc viết SQL tùy chỉnh –

+5

+1. Rất tiếc ['keep_default' không được chấp nhận ở Nam 0.8.1] (http://south.readthedocs.org/en/latest/releasenotes/0.8.1.html#keep-default-fully-deprecated) – Pankrat

+0

damn, Pankrat là đúng ... – galarant

2

Như đã đề cập trong các câu trả lời trước đó, cơ chế mặc định trong django được triển khai trong lớp mô hình và không liên quan đến di chuyển về phía nam.

Ngoài ra, từ phía nam 0,8, the keep_default flag is deprecated và sẽ không thêm giá trị mặc định vào mô hình của bạn.

Việc tôi làm để giải quyết vấn đề này là viết di chuyển tùy chỉnh để thêm giá trị mặc định. Bạn có thể làm điều đó bằng cách tạo ra một riêng biệt data migration:

./manage.py datamigration your_app_name migration_name 

và thêm dòng sau vào forwards chức năng:

orm.YourModel.objects.update(field_name = DEFAULT_VALUE) 

Ngoài ra, thay vì tạo ra một di dân mới, bạn có thể sửa đổi di cư ban đầu của bạn:

  1. thêm no_dry_run = True vào chính lớp đó (vì vậy bạn sẽ có quyền truy cập vào ORM).
  2. thêm orm.YourModel.objects.update(field_name = DEFAULT_VALUE) vào cuối hàm forwards.

Bằng cách này bạn không phải viết di chuyển ngược, vì bạn đã có một cột xóa ban đầu.

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