2011-08-18 34 views
11

tài liệu của Django là khá rõ ràng về việc lưu trữ chuỗi rỗng như "" chứ không phải là NULL ở mức cơ sở dữ liệu (như vậy chỉ có một khả năng định dạng cho dữ liệu trống):Django ORM, CharField và trống = True

Note giá trị chuỗi trống sẽ luôn được lưu trữ dưới dạng chuỗi rỗng, không phải là NULL. Chỉ sử dụng null = True cho các trường không phải chuỗi như số nguyên, booleans và ngày tháng. Đối với cả hai loại trường, bạn cũng sẽ cần phải đặt trống = True nếu bạn muốn cho phép giá trị trống trong biểu mẫu, vì tham số null chỉ ảnh hưởng đến bộ nhớ cơ sở dữ liệu (xem trống).

Tuy nhiên, sau khi thêm trường mới, tôi đã bắt đầu gặp phải IntegrityErrors trên trường mới (số điện thoại).

giá trị null trong cột "PHONE_NUMBER" vi phạm chế không null

Đó là mô hình trông như thế này với lĩnh vực mới (tôi đã thực hiện một sự chuyển đổi qua phía nam):

class Person(models.Model): 
    user = models.ForeignKey(User) 
    description = models.TextField(blank=True) 
    phone_number = models.CharField(blank=True) 

tôi kể từ khi (tạm thời) giải quyết vấn đề bằng cách thiết lập null = True trên phone_number, nhưng bây giờ tôi có hàng trăm mục có chuỗi rỗng, và một giá trị NULL duy nhất trong cơ sở dữ liệu của tôi. (Tôi cũng đã thử thêm mặc định = '' vào trường số điện thoại, nhưng tôi vẫn thấy sự cố IntegrityError.)

Trước đây tôi đã sử dụng MySQL, nhưng trong dự án này tôi đang sử dụng Postgres. Nỗ lực chèn SQL được tạo ra là:

'INSERT INTO "people_person" ("user_id", "description", "gender", "birthdate", "default_image_id", "zip_code", "beta_status") VALUES (%s, %s, %s, %s, %s, %s, %s) RETURNING "people_person"."id"'.

Mong đợi của tôi là Django sẽ chèn một chuỗi trống vào cột "số điện thoại", nhưng có vẻ như không làm như vậy. Điều khác tôi có thể mong đợi sẽ là Django để bao gồm một DEFAULT SET trong câu lệnh CREATE TABLE, nhưng nó không. Vì vậy, Postgres tức giận về NOT NULL trên cột đó.

Cảm ơn!

Trả lời

7

Như thường xảy ra với các sự cố có vẻ khó hiểu, vấn đề ở bàn tay là lỗi người dùng.

Ứng dụng của tôi có hai điểm vào - hai tệp WSGI, nhưng chỉ có một cơ sở mã. Thông thường, Apache sẽ chỉ tải lại mã của bạn nếu tệp được chạm. Kịch bản triển khai của tôi chỉ chạm vào một trong các tệp WSGI đó - điều đó có nghĩa là những người tiếp cận trang web của tôi thông qua tệp WSGI khác vẫn thấy mã cũ. Tệ hơn nữa, cơ sở dữ liệu đã được sửa đổi theo mã cũ đó, nhưng các mô hình vẫn như trước đây.

Điều này sẽ gây ra các sự cố IntegrityError. Django không biết về lĩnh vực phone_number, vì vậy mặc dù tôi đã thiết lập blank=True, Django không có nỗ lực để chèn một giá trị trống - và cơ sở dữ liệu của khóa học nghĩ rằng có nghĩa là NULL.

Điều này gây ra một loạt lỗi khác nhau để theo dõi, bao gồm cả lỗi trên. Thật ngạc nhiên khi các vấn đề thực sự khó khăn như thế này thường là do thiếu sót nhỏ - như một kịch bản triển khai tôi đã viết cách đây 2 tháng và quên cập nhật.

Cảm ơn bạn đã đọc, tôi đã bình chọn các câu trả lời khác, nhưng tôi cần chấp nhận câu trả lời của tôi vì đó là giải pháp cuối cùng.

6

Tôi phát hiện ra rằng nếu bạn đặt rõ ràng giá trị trường thành None bạn sẽ vẫn gặp phải các lỗi này. Nói cách khác, điều default= được áp dụng ngay khi bạn tạo đối tượng python, thay vào đó khi bạn lưu nó vào cơ sở dữ liệu.

Tôi đoán điều đó là hợp lý nhưng có một chút bất ngờ.

+0

điều tương tự dường như xảy ra nếu bạn chuyển 'None' cho hàm tạo (do đó, khi tạo) –

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