1

I'm switching from PHP to Django/Python, and one thing I don't really like about django so far is the ORM. When inserting new rows, it's fine, but when I want to SELECT something more specific, I find that the ORM is more troublesome than pure SQL, specially since I already know SQL quite well.

So, can I write pure SQL in Django, or I am forced to use the ORM?

If it's possible, examples on how to use SQL in django would be very welcome.

1

2 Answers 2

6

Yes! You can.

https://docs.djangoproject.com/en/1.7/topics/db/sql/

From Django's awesome documentation;

There are two ways;

  1. using a manager method raw()

    https://docs.djangoproject.com/en/1.7/topics/db/sql/#performing-raw-queries

    class Person(models.Model):
        first_name = models.CharField(...)
        last_name = models.CharField(...)
        birth_date = models.DateField(...)
    

    You could then execute custom SQL like so:

    >>> for p in Person.objects.raw('SELECT * FROM myapp_person'):
    ...     print(p)
    John Smith
    Jane Jones
    

    Use the following method to pass parameters.

    >>> lname = 'Doe'
    >>> Person.objects.raw('SELECT * FROM myapp_person WHERE last_name = %s', [lname])
    
  2. Executing custom SQL directly.

    https://docs.djangoproject.com/en/1.7/topics/db/sql/#executing-custom-sql-directly

    from django.db import connection
    def my_custom_sql(self):
        cursor = connection.cursor()
        cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
        cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
        row = cursor.fetchone()
    return row
    
Sign up to request clarification or add additional context in comments.

2 Comments

And be sure you don't forget to pass parameters as parameters, or you end up having your database SQL-injected!
This is exactly what I was looking for. Thank you for the comprehensive answer!
3

yes, it is. Suppose you have a model like this:

class Foo(models.Model):
    bar = models.CharField('bar', max_length=32)

you could write

Foo.objects.raw("SELECT bar from appname__foo LIMIT 5;")

or whatever SQL you like. the key is to use models.Model.objects.raw method.

It is up to you to make sure the query returns Foo objects though

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.