社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Django

django 执行原始SQL

BeginMan • 11 年前 • 8931 次点击  

一、参考文档和资料

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
 
8931 次点击  
文章 [ 1 ]  |  最新文章 11 年前
liguxk-weibo
Reply   •   1 楼
liguxk-weibo    11 年前

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