当前位置:网站首页>Django note 21: querying databases using native SQL
Django note 21: querying databases using native SQL
2022-06-12 13:21:00 【VV Ann's shallow singing】
Django Provides two ways to execute native SQL Code .
One is to use raw() function , One is Use connection.cursor().
But the authorities still recommend using native SQL Before , Try to explore first QuerySet A variety of API.
For now , Official documents provide a variety of API It can meet most application scenarios .
The following is the table of contents of this note :
- raw()
- connection.cursor()
- Multi database operation
1、raw()
This method can be used to manipulate native SQL, Then return model example :
We use Blog As an example , The code used is as follows :
for blog in Blog.objects.raw("select * from blog_blog"):
print(blog)
Copy code The effect of the above code is similar to Blog.objects.all() The results obtained are the same , But some operations are different , such as all().count() Can be obtained total , however raw() You can't do this .
It should be noted that ,raw() It doesn't detect the input SQL Code , Even if we use Blog This model To query Entry The data of , You can also return results , But all they return are Entry Table properties :
for blog in Blog.objects.raw("select * from blog_entry"):
print(blog.__dict__) # __dict__ The output is blog_entry Field of
Copy code in other words stay Blog.objects.raw() in , What really works is raw() This function , Ahead Blog It's just a shelf , Or way , It's to elicit raw() This function .
Custom return fields
stay raw() Functional SQL In the code , We can customize the selected fields , If you need to use a field that is not selected , Then the system will access the database again to get , The operation process is the same as that described above defer() The function is the same .
for item in Blog.objects.raw("select id from blog_blog"):
print(item.__dict__)
print(item.id, item.name)
print(item.__dict__)
{'_state': <django.db.models.base.ModelState object at 0x7fbd4165b6a0>, 'id': 2}
2 hunter
{'_state': <django.db.models.base.ModelState object at 0x7fbd4165b6a0>, 'id': 2, 'name': 'hunter'}
Copy code You can see , Among the returned results, the first output data is only id, Back , When we visit name Field time , I went to get it again name Field data .
Custom fields must contain primary keys
When we return a custom field , Must be to contain the primary key field , Otherwise, we will report an error when we get the information , For example, the following operation :
for blog in Blog.objects.raw("select name from blog_blog"):
print(blog.__dict__)
Copy code stay print(blog.dict) It's a mistake , There is no primary key information in the data
Custom return new field
Can follow QuerySet Of annotate Same operation , Custom new fields return , When getting, you can return directly according to the attribute value , such as :
entry = Entry.objects.raw("select *, date_format(pub_date, '%%Y-%%m') as date_1 from blog_entry")[0]
print(entry.date_1)
Copy code Passing variables
For input SQL Statement to pass variables :
name = "python"
Blog.objects.raw("select * from blog_blog where name = '%s'", [name])
Copy code 2、connection.cursor()
Django Introduced a more direct implementation SQL The way , The modules used are django.db.connction, Use of cursor and pymysql The library is used in the same way , The official example is as follows :
from django.db import connection
def my_custom_sql(self):
with connection.cursor() as cursor:
cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
row = cursor.fetchone()
return row
Copy code We need to pay attention to , If a parameter is passed in SQL in , You need to escape some symbols before you can use , such as :
cursor.execute("SELECT foo FROM bar WHERE baz = '30%'")
cursor.execute("SELECT foo FROM bar WHERE baz = '30%%' AND id = %s", [self.id])
Copy code among , Of the second sentence % Need to escape
adapter fetch The data of
adopt fetchone and fetchall() The data returned is only value It's worth it , There is no corresponding field key, If you can sacrifice performance and memory properly , In exchange for the convenience and accuracy of obtaining data , Officials offer such a way :
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()
]
Copy code After we finish cursor.execute(sql) after , hold cursor Pass in as a parameter dictfetchall Function , You can return a list of dictionaries
Introduce to you cursor.description, This returns a tuple of data , The element inside is also a tuple , The first element of a tuple is us select Field name .
therefore columns = [col[0] for col in cursor.description] This line of code gets all the specified field names
Examples of use :
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()
]
with connection.cursor() as cursor:
sql = "select id, name from blog_blog"
cursor.execute(sql)
results = dictfetchall(cursor)
print(results)
# The result returned :
# [{'id': 20, 'name': 'name_3'}, {'id': 21, 'name': 'name_4'}, {'id': 1, 'name': 'name_5'}]
Copy code In the process of my use , We use the context manager to get the cursor :
with connection.cursor() as cursor:
cursor.execute()
Copy code therefore , After use , There is no need to manually close , He is consistent with the following usage effect :
c = connection.cursor()
try:
c.execute(...)
finally:
c.close()
Copy code But the recommended way is the context manager , More elegant .
3、 Multi database operation
If the system uses multiple databases , So in use cursor When , You need to use it django.db.connections modular :
from django.db import connections
with connections['my_db_alias'].cursor() as cursor:
pass
Copy code The above is the whole content of this note , The next note will briefly introduce the operation of multiple databases .
This article starts with my official account of WeChat. :【Django note 】.
边栏推荐
- Online picture material
- 嵌入式系统概述3-嵌入式系统的开发流程和学习基础、方法
- 移动应用出海的“新大陆”
- Actual combat | realizing monocular camera ranging by skillfully using pose solution
- [cloud native | kubernetes] actual combat of ingress case
- 403 you don't have permission to access this resource
- leetcode 47. Permutations II 全排列 II(中等)
- 【云原生 | Kubernetes篇】深入了解Ingress
- 位图、布隆过滤器和哈希切分
- [cloud native | kubernetes] learn more about ingress
猜你喜欢

Further understanding of the network

unittest框架

Overview of embedded system 1- definition, characteristics and development history of embedded system

There was an error installing mysql. Follow the link below to CMD

Successful job hopping Ali, advanced learning

How to balance multiple losses in deep learning?

干货满满,这些知识你必须拿下

import torch_geometric 的Data 查看
![[brush title] probability of winning a draw](/img/f5/7e8dac944876f920db10508ec38e92.png)
[brush title] probability of winning a draw

What is the function tag? Article to understand its role and its best practices
随机推荐
hudi 键的生成(Key Generation)
一行代码实现shell if else逻辑
Unittest framework
【刷题篇】超级洗衣机
442 authors, 100 pages! It took Google 2 years to release the new benchmark big bench | open source
在 Debian 10 上独立安装MySQL数据库
[EDA] chip layout design: VLSI layout design using electric
C#DBHelper_ FactoryDB_ GetConn
【云原生 | Kubernetes篇】Kubernetes 网络策略(NetworkPolicy)
ITK multi-stage registration
嵌入式系統硬件構成-基於ARM的嵌入式開發板介紹
R language Visual facet chart, hypothesis test, multivariable grouping t-test, visual multivariable grouping faceting bar plot, adding significance level and jitter points
Software construction 03 regular expression
【云原生 | Kubernetes篇】Ingress案例实战
"New continent" of mobile application going to sea
达梦数据库DM8 windows环境安装
[wechat applet development] Part 1: development tool installation and program configuration
Help you with everything from the basics to the source code. Introduce the technology in detail
[cloud native | kubernetes] kubernetes networkpolicy
嵌入式系统硬件构成-嵌入式系统硬件体系结构