2009-03-03 29 views
19
class dbview(models.Model): 
    # field definitions omitted for brevity 
    class Meta: 
     db_table = 'read_only_view' 

def main(request): 
    result = dbview.objects.all() 

Caught một ngoại lệ khi render: (1054, "Unknown cột 'read_only_view id' trong 'danh sách trường'")Django: Truy vấn read-only xem không có khóa chính

không có khóa chính Tôi có thể thấy trong chế độ xem. Có cách giải quyết nào không?

Nhận xét:
Tôi không kiểm soát được chế độ xem tôi đang truy cập bằng Django. Trình duyệt MySQL hiển thị các cột ở đó nhưng không có khóa chính.

Trả lời

17

Khi bạn nói 'Tôi không kiểm soát chế độ xem tôi đang truy cập bằng Django. Trình duyệt MySQL hiển thị các cột ở đó nhưng không có khóa chính. '

Tôi giả sử bạn có nghĩa là đây là bảng kế thừa và bạn không được phép thêm hoặc thay đổi cột?

Nếu có và thực sự không phải là khóa chính (thậm chí là một chuỗi hoặc cột không phải int)) thì bảng chưa được thiết lập rất tốt và hiệu suất cũng có thể bốc mùi.

Nó không quan trọng với bạn. Tất cả những gì bạn cần là một cột được đảm bảo là duy nhất cho mỗi hàng. Đặt giá trị đó là 'primary_key = True trong mô hình của bạn và Django sẽ hài lòng.

  • Có một khả năng khác có thể là problemmatic. Nếu không có cột nào được đảm bảo là duy nhất thì bảng có thể đang sử dụng các khóa chính kết hợp. Tức là - nó xác định rằng hai cột được lấy cùng nhau sẽ cung cấp một khóa chính duy nhất. Đây là mô hình quan hệ hoàn toàn hợp lệ nhưng không được hỗ trợ bởi Django. Trong trường hợp đó, bạn không thể làm gì ngoài SQL thô trừ khi bạn có thể thêm một cột khác.
+0

Cảm ơn bạn rất nhiều, điều này thực sự thực sự hữu ích! – dmi

+0

Rất hữu ích. Một điều cần thêm; nếu cột bạn muốn sử dụng cho khóa chính là loại CHAR, cột đó không thể dài hơn 255 ký tự. –

+6

Điều này không thực sự giải quyết các câu hỏi, trong đó liên quan đến một cái nhìn db, không phải là một bảng. Bạn có chỉ định một trong các lĩnh vực của bạn như là một pk cho django, cho dù đó là hay không. Bạn có thể thoát khỏi điều này vì sẽ không bao giờ có bất kỳ chèn/cập nhật nào về mối quan hệ qua ORM. Xem [câu trả lời từ David S] (http://stackoverflow.com/a/11594959/519015) và bình luận của tôi để biết thêm về kỹ thuật này. –

1

Có trường đã được tạo tự động id khi bạn chạy syncdb (nếu không có khóa chính được xác định trong mô hình của bạn, thì Django sẽ chèn AutoField cho bạn).

Lỗi này có nghĩa là Django đang yêu cầu cơ sở dữ liệu của bạn cho trường id, nhưng không có trường nào tồn tại. Bạn có thể chạy django manage.py dbshell và sau đó DESCRIBE read_only_view; và đăng kết quả không? Điều này sẽ hiển thị tất cả các cột trong cơ sở dữ liệu.

Hoặc, bạn có thể bao gồm định nghĩa mô hình mà bạn đã loại trừ không? (và xác nhận rằng bạn chưa thay đổi định nghĩa mô hình kể từ khi bạn chạy syncdb?)

+0

Cảm ơn, tôi nên làm cho nó rõ ràng hơn ngay từ đầu. Vui lòng xem bản cập nhật. – dmi

+0

Tôi không yêu cầu xem hàng mà bạn đang truy cập, tôi chỉ muốn xem định nghĩa mô hình của bạn (không giống như vậy). – obeattie

+0

Các định nghĩa mô hình giống như sau: text = models.CharField() Tuy nhiên, tôi không thể xác định trường có 'primary_key = True' vì chế độ xem dường như không có khóa chính. – dmi

3

Nếu có thực sự là không có khóa chính trong chế độ xem, thì không có giải pháp thay thế.

Django requires each model to have exactly one field primary_key=True.

+0

Cảm ơn bạn! Nếu tôi không thể thấy khóa chính trong giao diện, điều đó có nghĩa là không có khóa chính ...? Đoán tôi sẽ chỉ trở lại SQL thô. – dmi

+0

Không nhất thiết. Xem bình luận của tôi dưới đây. –

12

Tôi gặp vấn đề này mọi lúc. Tôi có một cái nhìn mà tôi không thể hoặc không muốn thay đổi, nhưng tôi muốn có một trang để hiển thị thông tin tổng hợp (có thể trong phần quản trị). Tôi chỉ ghi đè tiết kiệm và nâng cao một NotImplementedError:

def save(self, **kwargs): 
     raise NotImplementedError() 

(mặc dù điều này có lẽ không cần thiết trong hầu hết các trường hợp, nhưng nó làm cho tôi cảm thấy tốt hơn một chút)

Tôi cũng thiết lập quản lý False trong Meta lớp học.

class Meta: 
     managed = False 

Sau đó, tôi chỉ chọn bất kỳ trường nào và gắn thẻ đó làm khóa chính. Nó không quan trọng nếu nó thực sự độc đáo với bạn chỉ là làm bộ lọc để hiển thị thông tin trên một trang, vv.

Dường như làm việc tốt cho tôi. Vui lòng cam kết nếu có bất kỳ vấn đề nào với kỹ thuật này mà tôi đang xem.

+2

Bạn có thể gắn thẻ một trường không phải là duy nhất làm khóa chính cho quyền truy cập chỉ đọc, nhưng điều này có phân nhánh cho những thứ như 'queryset.distinct(). Count()' và so sánh mẫu. Để giải quyết vấn đề này, bạn có thể xác định lại '__eq __()' trên mô hình. –

+0

Một cái gì đó bạn có thể làm để xem nếu bạn muốn có một id là sử dụng 'row_number()' chức năng (ít nhất là trong PostgreSQL). 'SELECT row_number() OVER (ORDER BY trường ASC) AS id,' – Bobort

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