startapp start create app sql django orm

start - django: ¿guía para ORM para usuarios de SQL?



django start app (4)

django tiene incorporado este complejo ORM, pero después de pasar mucho tiempo en él, todavía me resulta difícil realizar consultas que son notablemente simples en SQL. Incluso hay algunas cosas simples que no puedo encontrar a través del django ORM (por ejemplo, ''select distinct column1 from tablename'').

¿Hay alguna documentación que muestre "Para las sentencias de SQL comunes, aquí es cómo lo haces en django"?

(Probé con Google primero, pero o bien no está disponible o simplemente no puedo pensar en la consulta correcta ...)


Piénsalo de esta manera.

"Para los hack-sams de SQL comunes, ¿qué era lo orientado a objetos que se suponía que debía hacer en primer lugar?"

El problema no es que el ORM sea complejo. Es que su cerebro ha sido deformado en el molde de SQL, lo que hace que sea difícil ver los objetos con claridad.

Reglas generales:

  • Si crees que es un simple SELECCIONAR DE DONDE, detente. Pregunte qué objetos necesita ver en el conjunto de resultados. Luego encuentra esos objetos y trabaja con el administrador de objetos.

  • Si crees que es un JOIN simple, detente. Pregunta qué objeto principal quieres. Recuerde, los objetos no usan claves foráneas. Unirse no significa nada. Un objeto parece romper 1NF y contiene un conjunto completo de objetos relacionados dentro de él. Luego encuentre los objetos "primarios" y trabaje con el administrador de objetos. Utilice las consultas de objetos relacionados para encontrar objetos relacionados.

  • Si crees que es un OUTER JOIN, detente. Pregunta qué dos cosas quieres ver en el conjunto de resultados. Una combinación externa es cosas que unirán a UNIONED con cosas que no se unirán. ¿Cuáles son las cosas en primer lugar? Luego encuentre los objetos "primarios" y trabaje con el administrador de objetos. Algunos tendrán conjuntos de objetos relacionados. Algunos no lo harán.

  • Si cree que es un WHERE EXISTS o WHERE IN con una subconsulta, su modelo probablemente sea incompleto. A veces, requiere una unión elegante. Pero si está haciendo este tipo de comprobación, generalmente significa que necesita una propiedad en su modelo.

  • Si crees que necesitas SELECCIONAR DISTINCT, te has perdido el barco por completo. Eso es solo un conjunto de Python. Simplemente obtiene los valores de columna en un conjunto de Python. Esos son los valores distintivos.

  • Si crees que necesitas un GROUP BY, estás ignorando Python collections.defaultdict . Usar Python to para GROUP BY suele ser más rápido que preocuparse con SQL.

    Excepto por el almacenamiento de datos. Lo cual no deberías estar haciendo en Django. Debe usar SQLAlchemy para el almacenamiento de datos.


Un buen punto de partida para hacer consultas de Django es el propio Django.

http://docs.djangoproject.com/en/dev/topics/db/queries/

Aquí están algunos ejemplos:

select * from table = ModelName.objects.all()

filtración:

select * from table where column = ''foo'' = ModelName.objects.filter(column=''foo'')

Específicamente con respecto al uso de distinto, usted usa el método distinct () de un queryset de Django.

Aquí está el enlace relevante en la documentación. http://docs.djangoproject.com/en/dev/ref/models/querysets/#distinct

Actualización: el ORM lo ayuda permitiéndole usar interacciones orientadas a objetos con sus datos. No escribe código que traduce el conjunto de resultados de su consulta en un conjunto de objetos. Lo hace automáticamente Ese es el cambio fundamental en el proceso de pensamiento que tienes que hacer.

Empiezas a pensar en términos de ''Tengo este objeto, necesito obtener todos los otros objetos que son como'' Entonces puedes preguntarle al ORM por esos objetos. ORM, necesito todos los objetos de Class Product que tengan un atributo de color "azul"

El lenguaje ORM específico de Django para eso es:

products = Product.objects.filter(color=''blue'')

Esto se hace en lugar de:

  • escribiendo su consulta sql,
  • escapando correctamente todos los argumentos,
  • conectarse a la base de datos,
  • consultar la base de datos y manejar los errores de conexión / consulta,
  • obteniendo el conjunto de resultados,
  • iterar a través del conjunto de resultados traduciendo los valores devueltos en objetos adecuados a los que puede llamar métodos.

Ese es el valor de usar un ORM. Simplificación de código y tiempo de desarrollo reducido.


Para su práctica específica, lo haría así:

MyModel.objects.values_list(''column1'', flat=True).distinct()

Pero otros carteles son correctos para decir que no debería pensar ''¿cómo escribo este SQL en el ORM''? Cuando aprendiste Python, proveniente de Java o C ++ o lo que sea, pronto aprendiste a olvidarte de "cómo escribo este código Java en Python", y simplemente me concentré en resolver el problema usando Python. Lo mismo debería ser cierto de usar el ORM.


Hay algunas cosas que son ridículamente simples en SQL que son difíciles o imposibles a través de un ORM. Esto se conoce como " desajuste de impedancia relacional entre objetos ". Esencialmente, un ORM trata cada fila en una base de datos como un objeto separado. Por lo tanto, las operaciones que implican tratar los valores por separado de su fila se vuelven bastante desafiantes. Las versiones recientes de Django (1.1+) mejoran un poco esta situación con el soporte de agregación , pero para muchas cosas, solo SQL funcionará.

Con este fin, django ofrece varios métodos para dejar que caiga en raw sql de forma bastante simple. Algunos de ellos devuelven objetos del modelo como resultados, mientras que otros lo llevan hasta su conector DBAPI2. El nivel más bajo se ve así:

from django.db import connection cursor = connection.cursor() cursor.execute("SELECT DISTINCT column1 FROM tablename") row = cursor.fetchone()

Si desea devolver un conjunto de preguntas de una consulta SQL, use el comando raw () en el administrador de su modelo:

qs = ModelName.objects.raw("""SELECT first_name FROM myapp_modelname WHERE last_name = ''van Rossum''") for person in qs: print person.first_name # Result already available print person.last_name # Has to hit the DB again

Nota: raw () solo está disponible en la versión de desarrollo de Django, que debe fusionarse en trunk a partir de 1.2.

La información completa está disponible en la documentación en Realizar consultas SQL sin formato .