zoukankan      html  css  js  c++  java
  • django 执行原始SQL

    二、知识点总结

    When the model query APIs don’t go far enough, you can fall back to writing raw SQL.

    go far enough:远远不够fall back to:求助 
    raw:原始的,未加工的

    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字段、一个需求字段。这里主键字段不能省略,否则会出错,如下: 

    5、传递参数(Passing parameters into raw() )

    如果需要执行参数化查询,您可以使用params参数原始()

    注意两点: (1)、

    (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')

     通常我们不需要手动调用 transaction.commit_unless_managed( ),我们可以这样做:

    @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})

    下面贴一下常用的函数:

    然后,这个连接对象也提供了对事务操作的支持,标准的方法
    commit() 提交
    rollback() 回滚

    cursor用来执行命令的方法:
    callproc(self, procname, args):用来执行存储过程,接收的参数为存储过程名和参数列表,返回值为受影响的行数
    execute(self, query, args):执行单条sql语句,接收的参数为sql语句本身和使用的参数列表,返回值为受影响的行数
    executemany(self, query, args):执行单挑sql语句,但是重复执行参数列表里的参数,返回值为受影响的行数
    nextset(self):移动到下一个结果集

    cursor用来接收返回值的方法:
    fetchall(self):接收全部的返回结果行.
    fetchmany(self, size=None):接收size条返回结果行.如果size的值大于返回的结果行的数量,则会返回cursor.arraysize条数据.
    fetchone(self):返回一条结果行.
    scroll(self, value, mode='relative'):移动指针到某一行.如果mode='relative',则表示从当前所在行移动value条,如果 mode='absolute',则表示从结果集的第一行移动value条.

     
  • 相关阅读:
    系统学习DOM事件机制
    混合编程:域、桥与型变
    分层语言的混合编程
    投资第一定律
    元编程(运行时)模型
    泛型的第一性:同构、集合、抽象
    元编程沉思录
    思想是什么?经过严密的逻辑论证的观点的体系。
    编程语言概念的层次性与解释系统
    元编程沉思录(草稿)
  • 原文地址:https://www.cnblogs.com/chengJAVA/p/4432624.html
Copyright © 2011-2022 走看看