Py学习  »  Django

django 执行原始SQL

BeginMan • 12 年前 • 9070 次点击  

一、参考文档和资料

https://docs.djangoproject.com/en/1.2/topics/db/sql/

二、知识点总结

Django提供两种方式执行(performing)原始的SQL查询: (1)、Manager.raw():执行原始查询并返回模型实例

(2)、Executing custom SQL directly:直接执行自定义SQL,这种方式可以完全避免数据模型,而是直接执行原始的SQL语句。

三、raw()方法

The raw() manager method can be used to perform raw SQL queries that return model instances:   Manager.raw(raw_query, params=None, translations=None)

  >>> for p in Person.objects.raw('SELECT * FROM Person LIMIT 2'):
...     print p
John Smith
Jane Jones

注意,原始SQL里的model,如果在db_table 没有定义,则使用app的名称,后面下划线 后面接模型类的名称,如"Myblog_New";上面的例子,在定义类的时候已经这样处理了:

Class New(models.Model):
    ......
    ......
#自定义表名
    class Meta:
        db_table = 'New'

2、查询字段隐射到模型字段(Mapping query fields to model fields) raw() automatically maps fields in the query to fields on the model.并且是通过名称来匹配,这意味着我们可以使用SQL子句(clause)

>>> Person.objects.raw('''SELECT first AS first_name,
...                              last AS last_name,
...                              bd AS birth_date,
...                              pk as id,
...                       FROM some_other_table''')

返回一个RawQuerySet对象

3、索引查找(Index lookups)

first_person = Person.objects.raw('SELECT * from myapp_person')[0]
first_person = Person.objects.raw('SELECT * from myapp_person LIMIT 1')[0]
#然而,索引和切片不是在数据库级别上执行(除LIMIT外)

4、延迟模型字段(Deferring model fields) Fields may also be left out(left out:忽视,不考虑;被遗忘),这意味着该字段的查询将会被排除在根据需要时的加载。

>>> for p in Person.objects.raw('SELECT id, first_name FROM myapp_person'):
...     print p.first_name, # 这将检索到原始查询
...     print p.last_name # 这将检索需求
...
John Smith
Jane Jones

这个例子其实检索了三个字段,一个主键(必需)、一个原始SQL字段、一个需求字段。这里主键字段不能省略,否则会出错,如下: enter image description here

5、传递参数(Passing parameters into raw()) 如果需要执行参数化查询,您可以使用params参数原始()

enter image description here

(2)、必须使用[参数],否则出错:

(3)、这种方式不对:

Error:
>>> query = 'SELECT * FROM myapp_person WHERE last_name = %s' % lname
>>> Person.objects.raw(query)

四、直接执行自定义SQL

Manager.raw()远远不够,可直接执行自定义SQL,directly execute UPDATE, INSERT, or DELETE queries.

django.db.connection:代表默认的数据库连接
django.db.transaction:代表默认数据库事务(transaction
database connection调用connection.cursor() 得到一个游标(cursor)对象。
然后调用cursor.execute(sql, [params])执行SQL
cursor.fetchone() 或者 cursor.fetchall():返回结果行

如果执行修改操作,则调用transaction.commit_unless_managed()来保证你的更改提交到数据库。

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

    # 数据修改操作——提交要求
    cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
    transaction.commit_unless_managed()

    # 数据检索操作,不需要提交
    cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
    row = cursor.fetchone()

    return row

django.db.connections:针对使用多个数据库

from django.db import connections
cursor = connections['my_db_alias'].cursor


    
()
# Your code here...
transaction.commit_unless_managed(using='my_db_alias')

个人常用:

def Message(request,msg_id):
.........

where=msg_id
            sql='''
            select t.id, t.real_name, t2.* from auth_user t join (
            select max(is_red) as is_red,add_user_id,task_id from oa_red_yellow_card <br>       where msg_id=%s GROUP BY task_id,add_user_id)
            t2 ON t2.add_user_id=t.id

                ''' %where
            cursor = connection.cursor()
            cursor.execute(sql)
            fetchall = cursor.fetchall()

            red_yellow_card=[]
            for obj in fetchall:
                dic={}
                dic['user_id']=obj[0]
                dic['real_name']=obj[1]
                dic['is_red']=obj[2]
                dic['add_user']=obj[3]
                dic['task_id']=obj[4]
                red_yellow_card.append(dic)
            context['red_yellow_card']=red_yellow_card
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/145
 
9070 次点击  
文章 [ 1 ]  |  最新文章 12 年前
liguxk-weibo
Reply   •   1 楼
liguxk-weibo    12 年前

使用raw执行sql查询后,分页又用不了了,提示object of type 'RawQuerySet' has no len(),郁闷,有遇到过的吗?