Commit fd2f1800 authored by Jacob Kaplan-Moss's avatar Jacob Kaplan-Moss
Browse files

Fixed #14733: no longer "validate" .raw() queries.

Turns out that a lot more than just SELECT can return data, and this list is
very hard to define up front in a cross-database manner. So let's just assume
that anyone using raw() is at least halfway competant and can deal with
the error messages if they don't use a data-returning query.

Thanks to Christophe Pettus for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15803 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent f1f10a9c
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ class RawQuery(object):
    """

    def __init__(self, sql, using, params=None):
        self.validate_sql(sql)
        self.params = params or ()
        self.sql = sql
        self.using = using
@@ -62,11 +61,6 @@ class RawQuery(object):
        return [converter(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 other types of queries.')

    def __iter__(self):
        # Always execute a new query for a new iterator.
        # This could be optimized with a cache at the expense of RAM.
+10 −3
Original line number Diff line number Diff line
@@ -42,6 +42,10 @@ You could then execute custom SQL like so::
    John Smith
    Jane Jones

Of course, this example isn't very exciting -- it's exactly the same as
running ``Person.objects.all()``. However, ``raw()`` has a bunch of other
options that make it very powerful.

.. admonition:: Model table names

    Where'd the name of the ``Person`` table come from in that example?
@@ -56,9 +60,12 @@ You could then execute custom SQL like so::
    :attr:`~Options.db_table` option, which also lets you manually set the
    database table name.

Of course, this example isn't very exciting -- it's exactly the same as
running ``Person.objects.all()``. However, ``raw()`` has a bunch of other
options that make it very powerful.
.. warning::

    No checking is done on the SQL statement that is passed in to ``.raw()``.
    Django expects that the statement will return a set of rows from the
    database, but does nothing to enforce that. If the query does not
    return rows, a (possibly cryptic) error will result.

Mapping query fields to model fields
------------------------------------
+0 −4
Original line number Diff line number Diff line
@@ -169,10 +169,6 @@ class RawQueryTests(TestCase):
        authors = Author.objects.all()
        self.assertSuccessfulRawQuery(Author, query, authors, expected_annotations)

    def testInvalidQuery(self):
        query = "UPDATE raw_query_author SET first_name='thing' WHERE first_name='Joe'"
        self.assertRaises(InvalidQuery, Author.objects.raw, query)

    def testWhiteSpaceQuery(self):
        query = "    SELECT * FROM raw_query_author"
        authors = Author.objects.all()