Django documentation

当前文档仅适用于 Django SVN 版本,与上个版本有显著不同。上个版本文档请查阅 Django 1.0

执行原始 SQL 查询(Performing raw SQL queries)

你可以自由地在自定义的 model 方法和模块级(module-level)方法中使用原始 SQL 语句。 django.db.connection 对象表示当前数据库连接,而 django.db.transaction 表示当前数据库的事务。调用 connection.cursor() 会得到一个游标对象,可以用它来操作数据库。然后,调用 cursor.execute(sql, [params]) 执行 SQL ,然后调用 cursor.fetchone()cursor.fetchall() 返回结果行。在执行了一个数据更改的操作之后,你应该调用 transaction.commit_unless_managed() 以确保数据改动被提交到数据库。如果你的操作仅仅是一个读取操作,那么没必要提交。例如:

def my_custom_sql(self):
    from django.db import connection, transaction
    cursor = connection.cursor()

    # Data modifying operation - commit required
    cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
    transaction.commit_unless_managed()

    # Data retrieval operation - no commit required
    cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
    row = cursor.fetchone()

    return row

事务和原始 SQL (Transactions and raw SQL)

如果你正在使用事务装饰器(例如 commit_on_success)来修饰视图和提供事务控制。你不必手动调用 transaction.commit_unless_managed(),当然如果你愿意的话,可以手动调用,但是一般情况下用不着这么做,这是因为装饰器会为你自动提交事务。但是,如果你不手动提交修改,你需要使用 transaction.set_dirty() 将事务标识为已脏

@commit_on_success
def my_custom_sql_view(request, value):
    from django.db import connection, transaction
    cursor = connection.cursor()

    # Data modifying operation
    cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [value])

    # Since we modified data, mark the transaction as dirty
    transaction.set_dirty()

    # Data retrieval operation. This doesn't dirty the transaction,
    # so no call to set_dirty() is required.
    cursor.execute("SELECT foo FROM bar WHERE baz = %s", [value])
    row = cursor.fetchone()

    return render_to_response('template.html', {'row': row})

使用 Django ORM 对数据库进行修改时,Django 会自动调用 set_dirty() 。但如果你使用了原始 SQL ,Django 就无法获得你的 SQL 是否修改了数据。只有手动调用 set_dirty() 才能确保 Django 知晓哪些修改必须被提交。

连接和游标(Connections and cursors)

连接(connection)游标(cursor) 实现了大部分标准的 Python DB-API (除了 事务处理(transaction handling) 之外)。 如果你并不熟悉 Python DB-API,建议您 cursor.execute() 中的 SQL 语句使用 "%s" 占位符,而不是直接在 SQL 中添参数。如果你使用了占位符,幕后的数据库类库将自动添加引号,并对参数中的某些字符进行转义(要注意 Django 使用 "%s" 占位符,而不是 "?" 占位符--为 Python 中的 SQLite 库所用,这样做是为了使用方便和用法一致。)

更简单的选项(An easier option?)

最后要注意地是:如果你仅仅是想自定义 WHERE 从句,你只要根据标准的查询集 API ,使用在 extra clause 中提及的 where, tablesparams 参数即可。

Questions/Feedback

Having trouble? We'd like to help!