1
0
mirror of https://github.com/django/django.git synced 2025-10-31 01:25:32 +00:00

Fixed #11863: added a Model.objects.raw() method for executing raw SQL queries and yield models.

See `docs/topics/db/raw.txt` for details.

Thanks to seanoc for getting the ball rolling, and to Russ for wrapping things up.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@11921 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jacob Kaplan-Moss
2009-12-20 02:46:58 +00:00
parent 25ab93457c
commit 20ad30713e
9 changed files with 627 additions and 23 deletions

View File

@@ -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):
"""