简介
本文主要整理了Django多种针对postgresql数据库所支持的查询方式
目录
简介
目录
正文
一、使用Python直接操作数
二、使用Django执行数据库查询语句
Django 使用游标执行SQL查询语句
Django raw执行SQL查询语句
三、Django使用extra拆分SQL语句执行
参数说明
四、使用Django ORM进行简单数据库查询
五、使用双下划线查询
六、关联表使用下划线查询
外键关联查询
多对多关系查询
对比extra
七、使用Django-filter查询
总结
正文
这种方式是最基本也是最全面的对数据库操作,因为本质上是写SQL语句操作数据库。
import psycopg2
# 连接数据库有两种方式
# 方式一
conn = psycopg2.connect("dbname=test user=postgres password=secret host=xx.xx.xx.xx post=5432")
# 方式二
conn = psycopg2.connect(
database="test",
user="postgres",
password="secret",
host="xx.xx.xx.xx",
port="5432"
)
# 获取游标
cursor = conn.cursor()
try:
# 需要执行的命令
cursor.execute("SELECT name,setting FROM pg_settings")
#返回一行
raw = cursor.fetchone()
# 获取结果集
results=cursor.fetchall()
# 提交命令
conn.commit()
except Exception as e:
print(str(e))
else:
print(results)
# 关闭游标
cursor.close()
# 关闭数据库链接
conn.close()
优点:对数据库的支持是最贴切的。
缺点:需要关注数据库的连接,提交,关闭,以及复杂SQL的编辑。不支持explain()查看数据库执行计划
这种方式和第一种直接用Python操作数据库的方法是一样的,区别只是不需要自己去做数据库链接也不需要手动commit,在Django项目启动的时候,会根据在setting的配置连接数据库。返回的数据类型是tuple或者tuple_List
from django.db import connection
cursor = connection.cursor()
#查询
cursor.execute("select * from user")
#返回一行
raw = cursor.fetchone()
#返回所有
results = cursor.fetchall()
# 批量操作
cursor.executemany(
"insert into user (id,name,age) values ({},{},{})",
[(1,"aaa",18)),(2,"bbb",19),(3,"ccc",20)]
)
今天发现自己写sql的有个bug,但是之前在Django的shell的环境上运行时没有问题的,因此特别更新记录一下
# 批量操作
cursor.executemany(
"insert into user (id,name,age) values (%s,%s,%s)",
[(1,"aaa",18)),(2,"bbb",19),(3,"ccc",20)]
)
在Python直接操作数据库的情况下,批量操作应该使用 %s,而不是使用{}。同时占位符的数量=需要插入字段的数量。而不是插入的行数
同时使用这种方法可以进行跨数据库查询,通过setting配置多数据库参数。
from django.db import connections
cursor = connections["db1"].cursor()
cursor = connections["db2"].cursor()
优点:不需要关注数据库的连接,提交和关闭,只需要专注于SQL的编辑
缺点:还是需要编辑复杂的SQL语句。不支持explain()查看数据库执行计划
from django.db import models
class user(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
age = models.IntegerField()
class Meta:
db_table='user'
results = user.objects.raw("select * from user")
这种方法可以使用query查看执行的SQL语句,返回的类型可以像QuerySet一样遍历。
但是有个很大的问题,就是raw并不针对任意model,下面这种情况也是可以执行的:
from django.db import models
class user(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=5)
age = models.IntegerField()
class Meta:
db_table='user'
class animal(model.Model):
kind = models.CharField(primary_key=True, max_length=5)
sex = models.BooleanField()