☆Django☆---orm 字段 数据库查询优化 事务

1. 前言

Django 是一个基于 Python 的 Web 框架,是一个高度模块化的MVC框架。在 Django 中,ORM 是一个非常重要的组件,它让用户可以通过Python代码来操作数据库而无需写 SQL 语句,提高了开发效率。ORM 封装了数据表的操作,使得开发人员只需要面向对象编程,不必关注数据库的具体实现。本文主要介绍 Django 中 ORM 的基础知识、ORM 查询调优以及事务管理。

2. ORM 字段

2.1 字段类型

Django ORM 提供了多种字段类型,包括基础字段类型和高级字段类型。基础字段类型包括 CharField、IntegerField、SmallIntegerField、DateTimeField 等。高级字段类型包括 ForeignKey、OneToOneField、ManyToManyField 等。需要根据实际情况选择合适的字段类型,以确保存储数据的正确性和可扩展性。

from django.db import models

class Person(models.Model):

name = models.CharField(max_length=30)

age = models.IntegerField()

create_time = models.DateTimeField(auto_now_add=True)

2.2 字段属性

Django ORM 提供了多种字段属性,包括 null、blank、default、unique、choices 等。需要根据实际情况选择合适的字段属性,以确保存储数据的正确性和可用性。

from django.db import models

class Person(models.Model):

name = models.CharField(max_length=30)

age = models.IntegerField(null=True, blank=True)

create_time = models.DateTimeField(auto_now_add=True)

is_deleted = models.BooleanField(default=False)

3. ORM 数据库查询优化

3.1 选择查询集

ORM 查询的结果是一个查询集,可以对查询集进行操作,比如过滤、排序、分页等。尽量减少查询的数量,使用 values() 或 values_list() 方法可以只选择需要的字段,避免查询所有字段。

# 不使用选择查询集的代码

from myapp.models import Person

persons = Person.objects.all()

for person in persons:

print(person.name)

# 使用选择查询集的代码

from myapp.models import Person

persons = Person.objects.all().values('name')

for person in persons:

print(person['name'])

3.2 减少查询次数

根据查询结果的使用情况,减少查询次数可以提高查询效率。可以使用 select_related() 和 prefetch_related() 方法来处理多对一和多对多关系的查询。

# 使用 N+1 Queries 的代码

from myapp.models import Person, Address

persons = Person.objects.all()

for person in persons:

address = person.address_set.all()

print(person.name, address)

# 使用 prefetch_related 的代码

from myapp.models import Person, Address

persons = Person.objects.all().prefetch_related('address_set')

for person in persons:

address = person.address_set.all()

print(person.name, address)

3.3 使用 Raw SQL

如果需要执行复杂的查询,ORM 无法满足需求,可以使用 Raw SQL。但要注意 Raw SQL 会增加代码复杂性和可维护性,需要注意 SQL 注入漏洞。

from django.db import connection

def get_person_by_sql(name):

with connection.cursor() as cursor:

sql = "SELECT * FROM myapp_person WHERE name LIKE %s"

cursor.execute(sql, (f'%{name}%',))

persons = cursor.fetchall()

return persons

4. ORM 事务

4.1 事务的概念

事务是一组数据库操作,要么全部成功,要么全部失败。当多个应用程序同时访问数据库时,如果不使用事务,可能会发生数据不一致的情况。Django ORM 支持事务操作,保证数据的一致性和完整性。

4.2 使用事务

在 Django ORM 中,可以使用 with atomic() 来开启一个事务块。

from django.db import transaction

@transaction.atomic

def transfer_money(from_user, to_user, amount):

from_user.balance -= amount

to_user.balance += amount

from_user.save()

to_user.save()

4.3 事务嵌套

在某些情况下,需要在一个事务块内嵌套另一个事务块。这个时候可以使用 with transaction.atomic(using='other_database') 指定使用另一个数据库进行事务操作。需要注意,只有支持事务操作的数据库才能进行事务嵌套。

from django.db import transaction

@transaction.atomic

def transfer_money(from_user, to_user, amount):

from_user.balance -= amount

to_user.balance += amount

from_user.save()

to_user.save()

with transaction.atomic(using='log_database'):

record_transfer_log(from_user, to_user, amount)

5. 总结

本文主要介绍了 Django ORM 的字段类型和属性、数据库查询优化、事务管理等方面的知识。通过合理使用 ORM,可以大大提高开发效率和应用的性能。同时,对于需要高性能的应用,需要使用原生 SQL 来进行查询和操作,充分利用数据库的性能。

后端开发标签