When to Drop to SQL

The ORM covers most cases well. These are the ones where it stops helping.

Reporting queries with several aggregates and joins, where the ORM version becomes longer and less readable than the SQL.

Window functions and set operations, where support is awkward or absent.

Bulk changes: one UPDATE beats loading ten thousand objects to save each one.

Anything you need the plan for, because you cannot optimize what you cannot read.

Always parameterise. Passing values as parameters rather than formatting them into the SQL string is what keeps injection impossible.

This is the same point as the Django security module, seen from underneath: raw() with parameters is safe, raw() with string formatting is the one real way to reintroduce SQL injection into a Django project, and the two look almost identical.

✦ The most useful habit

Print the SQL your ORM generates. In Django, str(queryset.query), or the Debug Toolbar. Do it for the queries on your busiest page once, and you will find something you did not expect. Everyone does.

Mark this lesson complete

Signed in, your progress follows you to every device.

Next: Practice Test →
← Back