diff options
Diffstat (limited to 'django/db/models/sql/query.py')
| -rw-r--r-- | django/db/models/sql/query.py | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index f3e24ed8ee..9ecf273be3 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -15,7 +15,7 @@ from django.db.backends.util import truncate_name from django.db import connection from django.db.models import signals from django.db.models.fields import FieldDoesNotExist -from django.db.models.query_utils import select_related_descend +from django.db.models.query_utils import select_related_descend, InvalidQuery from django.db.models.sql import aggregates as base_aggregates_module from django.db.models.sql.expressions import SQLEvaluator from django.db.models.sql.where import WhereNode, Constraint, EverythingNode, AND, OR @@ -23,7 +23,42 @@ from django.core.exceptions import FieldError from datastructures import EmptyResultSet, Empty, MultiJoin from constants import * -__all__ = ['Query', 'BaseQuery'] +__all__ = ['Query', 'BaseQuery', 'RawQuery'] + +class RawQuery(object): + """ + A single raw SQL query + """ + + def __init__(self, sql, connection, params=None): + self.validate_sql(sql) + self.params = params or () + self.sql = sql + self.connection = connection + self.cursor = None + + def get_columns(self): + if self.cursor is None: + self._execute_query() + return [column_meta[0] for column_meta in self.cursor.description] + + def validate_sql(self, sql): + if not sql.lower().strip().startswith('select'): + raise InvalidQuery('Raw queries are limited to SELECT queries. Use ' + 'connection.cursor directly for types of queries.') + + def __iter__(self): + # Always execute a new query for a new iterator. + # This could be optomized with a cache at the expense of RAM. + self._execute_query() + return self.cursor + + def __repr__(self): + return "<RawQuery: %r>" % (self.sql % self.params) + + def _execute_query(self): + self.cursor = self.connection.cursor() + self.cursor.execute(self.sql, self.params) class BaseQuery(object): """ |
