2009-03-03 18 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() 

detectó una excepción al intentar mostrar: (1054, "Desconocido columna 'read_only_view Identificación' en 'lista de campos'")Django: Consulta de sólo lectura ver con ninguna clave principal

No es no hay clave principal que puedo ver en la vista. ¿Hay alguna solución?

Comentario:
No tengo control sobre la vista a la que estoy accediendo con Django. El navegador MySQL muestra columnas allí pero ninguna clave principal.

Respuesta

17

Cuando dice 'no tengo ningún control sobre la vista accedo con Django. El navegador MySQL muestra columnas allí pero ninguna clave principal. '

Supongo que quiere decir que esta es una tabla heredada y no tiene permitido agregar ni cambiar columnas.

Si es así y realmente no hay una clave principal (incluso una cadena o una columna que no sea int *), entonces la tabla no se ha configurado muy bien y el rendimiento puede apestoso.

Sin embargo, no le importa. Todo lo que necesita es una columna que garantice ser única para cada fila. Establezca que sea 'primary_key = True en su modelo y Django estará contento.

  • Hay otra posibilidad que podría ser problemática. Si no hay ninguna columna que garantice que sea única, la tabla podría estar utilizando claves primarias compuestas. Es decir, está especificando que dos columnas juntas proporcionarán una clave primaria única. Este es un modelado relacional perfectamente válido pero desafortunadamente no respaldado por Django. En ese caso, no puede hacer mucho más que SQL sin formato a menos que pueda agregar otra columna.
+0

Muchas gracias, ¡esto es realmente muy útil! – dmi

+0

Muy útil. Una cosa para agregar; si la columna que desea utilizar para una clave principal es un tipo CHAR, no puede tener más de 255 caracteres. –

+6

Esto realmente no aborda la pregunta, que se refiere a una vista db, no a una tabla. Usted debe especificar uno de sus campos como pk para django, ya sea que lo sea o no. Puede salirse con la suya ya que nunca habrá ninguna inserción/actualización en la relación a través del ORM. Ver [la respuesta de David S] (http://stackoverflow.com/a/11594959/519015) y mi comentario al respecto para obtener más información sobre esta técnica. –

1

Debe haber sido un campo generado automáticamente id cuando ejecutó syncdb (si no hay una clave principal definida en su modelo, entonces Django insertará un AutoField para usted).

Este error significa que Django le está pidiendo a su base de datos el campo id, pero no existe ninguno. ¿Puedes ejecutar django manage.py dbshell y luego DESCRIBE read_only_view; y publicar el resultado? Esto mostrará todas las columnas que están en la base de datos.

Como alternativa, ¿puede incluir la definición de modelo que excluyó? (Y confirmar que no se ha alterado la definición del modelo, ya que ejecutó syncdb?)

+0

Gracias, debería haberlo dejado más claro al principio. Por favor mira la actualización. – dmi

+0

No estoy pidiendo ver la fila a la que está accediendo, solo quiero ver la definición de su modelo (no es lo mismo). – obeattie

+0

Las definiciones del modelo son las siguientes: text = models.CharField() Sin embargo, no puedo definir un campo con 'primary_key = True' porque la vista no parece tener una clave principal. – dmi

12

Tengo este problema todo el tiempo. Tengo una opinión de que no puedo o no quiero cambiar, pero quiero tener una página para mostrar información compuesta (tal vez en la sección de administración). Acabo de anular el parada de levantar una NotImplementedError:

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

(aunque esto probablemente no es necesario en la mayoría de los casos, pero me hace sentir un poco mejor)

que también estableció las arreglé para False en el Meta clase.

class Meta: 
     managed = False 

Luego selecciono cualquier campo y lo etiqueto como la clave principal. No importa si es realmente único con usted solo está haciendo filtros para mostrar información en una página, etc.

Parece que funciona bien para mí. Por favor comente si hay algún problema con esta técnica que estoy pasando por alto.

+2

Puede etiquetar un campo no exclusivo como clave principal para el acceso de solo lectura, pero esto tiene ramificaciones para cosas como 'queryset.distinct(). Count()' y comparaciones de instancias. Como una solución alternativa para este último, puede redefinir '__eq __()' en el modelo. –

+0

Algo que puede hacer a la vista si quiere tener una identificación es utilizar la función 'row_number()' (al menos en PostgreSQL). 'SELECT row_number() OVER (ORDER BY campo ASC) AS id,' – Bobort

Cuestiones relacionadas