3.执行原始SQL

2019-09-25  本文已影响0人  zxhChex

利用 .raw() 执行原始 SQL

Manager.raw(raw_query, params=None, translations=None)

基本查询

In [40]: from users.models import UsersProfile as Users

In [41]: Users.objects.raw("select * from user_profile")
Out[41]: <RawQuerySet: select * from user_profile>

In [42]: u = Users.objects.raw("select * from user_profile")

获取基本信息

1. 表模型

In [43]: u.model
Out[43]: users.models.UsersProfile

2. 所有的表字段名

In [45]: u.columns
Out[45]:
['id',
 'password',
 'last_login',
 'is_superuser',
 'username',
 'first_name',
 'last_name',
 'email',
 'is_staff',
 'is_active',
 'date_joined',
 'nick_name',
 'birday',
 'gender',
 'address',
 'mobile',
 'image']

3. Django 的那个数据库

In [46]: u.db
Out[46]: 'default'

4. 重现查询语句

In [48]: u.raw_query
Out[48]: 'select * from user_profile'

获取数据

raw 返回对象可迭代,可切片

In [52]: for user in u:
    ...:     print(user.id,user.username)
    ...:
1 admin
2 author1
3 author2
4 xiguatain
5 shark1
6 sharksuper

指定字段查询

指定字段查询时候,必须包含表主键字段(比如 id 字段)

官方提示: Django使用主键来标识模型实例,因此它必须始终包含在原始查询中。

In [59]: uf = Users.objects.raw("select id, username from user_profile"
    ...:
    ...: )

In [60]: uf[1].id
Out[60]: 1

In [61]: uf[1].username
Out[61]: 'admin'

In [62]: uf[1].email  # 注意这里会再次触发查询数据库的操作
Out[62]: 'admin@shark.com'

传递参数个 raw

传参时应该始终使用 params 参数

where 条件查询

In [66]: usig = Users.objects.raw("select id, username from user_profil
    ...: e where username=%s", [name])

注意: 上述的 %s 不应该写成带引号的 '%s'
这会导致 SQL 注入

得到的结果任然是给集合

In [67]: usig
Out[67]: <RawQuerySet: select id, username from user_profile where username=admin>

获取数据

In [70]: usig[0].id
Out[70]: 1

In [71]: usig[0].username
Out[71]: 'admin'

直接执行自定义

直接执行 UPDATE,INSERT 或 DELETE

In [95]: with connection.cursor() as cursor:
    ...:     cursor.execute("update user_profile set email='1@100.com'
    ...: where id=%s;", params=[2])
    ...:     cursor.execute("select id, email from user_profile where i
    ...: d=%s;", params=[2])
    ...:     raw = cursor.fetchone()
    ...:     print(raw)
    ...:
(2, '1@100.com')

修改结果集的类型

得到包含字典类型的结果集

定义函数

def dictfetchall(cursor):
    "Return all rows from a cursor as a dict"
    columns = [col[0] for col in cursor.description]
    return [
        dict(zip(columns, row))
        for row in cursor.fetchall()
    ]

使用

In [99]: c = cursor.cursor()

In [100]: dictfetchall(c)
Out[100]: [{'id': 9, 'username': 'aa'}, {'id': 1, 'username': 'admin'}]

得到包含对象类型的结果集

定义函数

from collections import namedtuple

def namedtuplefetchall(cursor):
    "Return all rows from a cursor as a namedtuple"
    desc = cursor.description
    nt_result = namedtuple('Result', [col[0] for col in desc])
    return [nt_result(*row) for row in cursor.fetchall()]

使用

In [113]: c.execute("select id,username from user_profile limit 2")
Out[113]: 2

In [114]: results = namedtuplefetchall(c)

In [115]: results
Out[115]: [Result(id=9, username='aa'), Result(id=1, username='admin')]

In [116]: results[0].username
Out[116]: 'aa
上一篇 下一篇

猜你喜欢

热点阅读