Chi*_*fir 2 python django overriding transactions python-3.x
我正在覆盖save()模型中的默认方法,并在那里创建一个相关的模型实例:
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
parent_folder = None
if self.parent:
parent_folder = self.parent.task_folders.all().first()
folder, created = Folder.objects.get_or_create(
project=self.project,
task=self,
parent=parent_folder,
defaults={'name': self.name,
'project': self.project,
'task': self,
'creator': self.creator,
'parent': parent_folder,
'is_root': True
})
Run Code Online (Sandbox Code Playgroud)
问题是 - 我应该transaction.atomic在这里使用吗?它如何与save()方法一起工作?
小智 5
不,您不需要在Django 模型中显式使用原子事务(例如“@transaction.atomic”或“with transaction.atomic():”)来重写“save()”,因为原子事务隐式用于重写“save” ()“默认情况下。
使用PostgreSQL,我尝试了原子事务是否默认隐式用于重写的“save()”,或者不使用下面的代码。* “SELECT”、“INSERT”、“UPDATE”和“DELETE”查询由“models.py”上覆盖的“save()”中的“Animal”类代码运行,如下所示:
# "store/models.py"
from django.db import models
class Animal(models.Model):
name = models.CharField(max_length=30)
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
def save(self, *args, **kwargs):
animal = Animal.objects.all() # For "SELECT" query
print(animal) # Needed to run "SELECT" query
Animal(name='Dog').save() # For "INSERT" query
Animal.objects.filter(name="Dog").update(name="Cat") # For "UPDATE" query
Animal.objects.filter(name="Cat").delete() # For "DELETE" query
def __str__(self):
return self.first_name + " " + self.last_name
Run Code Online (Sandbox Code Playgroud)
然后,我添加一个人来运行“Person”类中重写的“save()”,如下所示。*实际上,“John Smith”这个人没有被添加,因为重写的“save()”没有“super().save(*args, **kwargs)”:
现在,在“BEGIN”和“COMMIT”查询之间,“SELECT”、“INSERT”、“UPDATE”和“DELETE”查询由覆盖的“save()”中的“Animal”类代码运行。因此,默认情况下,原子事务隐式用于重写的 save()。*下面这些日志是PostgreSQL的查询日志。您可以检查在 PostgreSQL 上,如何使用事务查询(例如“BEGIN”和“COMMIT”)记录 SQL 查询:
此外,在重写的“save()”末尾,我添加了“super().save(*args, **kwargs)”,它运行“INSERT”查询,如下所示:
# "store/models.py"
from django.db import models
class Animal(models.Model):
name = models.CharField(max_length=30)
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
def save(self, *args, **kwargs):
animal = Animal.objects.all() # For "SELECT" query
print(animal) # Needed to run "SELECT" query
Animal(name='Dog').save() # For "INSERT" query
Animal.objects.filter(name="Dog").update(name="Cat") # For "UPDATE" query
Animal.objects.filter(name="Cat").delete() # For "DELETE" query
super().save(*args, **kwargs) # For "INSERT" query
def __str__(self):
return self.first_name + " " + self.last_name
Run Code Online (Sandbox Code Playgroud)
然后,我添加一个人来运行“Person”类中重写的“save()”,如下所示。*这次,添加了“John Smith”这个人,因为重写的“save()”有“super().save(*args, **kwargs)”:
现在,“INSERT”查询由“super().save(*args, **kwargs)”在“BEGIN”和“COMMIT”查询之间的“DELETE”查询之后运行,如下所示:
接下来,在重写的“save()”的开头,我添加“super().save(*args, **kwargs)”,它运行“INSERT”查询,如下所示:
# "store/models.py"
from django.db import models
class Animal(models.Model):
name = models.CharField(max_length=30)
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
def save(self, *args, **kwargs):
super().save(*args, **kwargs) # For "INSERT" query
animal = Animal.objects.all() # For "SELECT" query
print(animal) # Needed to run "SELECT" query
Animal(name='Dog').save() # For "INSERT" query
Animal.objects.filter(name="Dog").update(name="Cat") # For "UPDATE" query
Animal.objects.filter(name="Cat").delete() # For "DELETE" query
def __str__(self):
return self.first_name + " " + self.last_name
Run Code Online (Sandbox Code Playgroud)
然后,我添加一个人来运行“Person”类中重写的“save()”,如下所示。*这次,添加了“John Smith”这个人,因为重写的“save()”有“super().save(*args, **kwargs)”:
现在,“INSERT”查询由“super().save(*args, **kwargs)”在“BEGIN”和“COMMIT”查询之间的“SELECT”查询之前运行,如下所示:
接下来,对于重写的“save()”,我放置“@transaction.atomic”装饰器,如下所示:
# "store/models.py"
from django.db import models
class Animal(models.Model):
name = models.CharField(max_length=30)
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
@transaction.atomic # Here
def save(self, *args, **kwargs):
animal = Animal.objects.all() # For "SELECT" query
print(animal) # Needed to run "SELECT" query
Animal(name='Dog').save() # For "INSERT" query
Animal.objects.filter(name="Dog").update(name="Cat") # For "UPDATE" query
Animal.objects.filter(name="Cat").delete() # For "DELETE" query
def __str__(self):
return self.first_name + " " + self.last_name
Run Code Online (Sandbox Code Playgroud)
或者,对于覆盖的“save()”,我放置“with transaction.atomic():”,如下所示:
# "store/models.py"
from django.db import models
class Animal(models.Model):
name = models.CharField(max_length=30)
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
def save(self, *args, **kwargs):
with transaction.atomic(): # Here
animal = Animal.objects.all() # For "SELECT" query
print(animal) # Needed to run "SELECT" query
Animal(name='Dog').save() # For "INSERT" query
Animal.objects.filter(name="Dog").update(name="Cat") # For "UPDATE" query
Animal.objects.filter(name="Cat").delete() # For "DELETE" query
def __str__(self):
return self.first_name + " " + self.last_name
Run Code Online (Sandbox Code Playgroud)
然后,我添加一个人来运行“Person”类中重写的“save()”,如下所示:
现在,“SAVEPOINT”和“RELEASE SAVEPOINT”查询分别在“BEGIN”查询之后和“DELETE”查询之后在“BEGIN”和“COMMIT ”之间由“@transaction.atomic”装饰器或“with transaction.atomic():”运行”查询如下图:
接下来,对于重写的“save()”,如下所示:
# "store/models.py"
from django.db import models
class Animal(models.Model):
name = models.CharField(max_length=30)
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
def save(self, *args, **kwargs):
animal = Animal.objects.all() # For "SELECT" query
print(animal) # Needed to run "SELECT" query
Animal(name='Dog').save() # For "INSERT" query
Animal.objects.filter(name="Dog").update(name="Cat") # For "UPDATE" query
Animal.objects.filter(name="Cat").delete() # For "DELETE" query
def __str__(self):
return self.first_name + " " + self.last_name
Run Code Online (Sandbox Code Playgroud)
我将'ATOMIC_REQUESTS': True放入“settings.py”中的PostgreSQL 设置:
# "core/settings.py"
DATABASES = {
'default':{
'ENGINE':'django.db.backends.postgresql',
'NAME':'postgres',
'USER':'postgres',
'PASSWORD':'admin',
'HOST':'localhost',
'PORT':'5432',
'ATOMIC_REQUESTS': True, # Here
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我添加一个人来运行“Person”类中重写的“save()”,如下所示:
现在,“SAVEPOINT”和“RELEASE SAVEPOINT”查询由“ATOMIC_REQUESTS”运行:分别在“Animal”类代码运行的“SELECT”查询之前和“COMMIT”查询之前为 True ,并且在“之间添加了2 个蓝色的“SELECT”查询BEGIN”和“COMMIT”查询如下所示:
接下来,对于重写的“save()”,我放置了“@transaction.atomic”装饰器和“with transaction.atomic():”,如下所示:
# "store/models.py"
from django.db import models
class Animal(models.Model):
name = models.CharField(max_length=30)
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
@transaction.atomic # Here
def save(self, *args, **kwargs):
with transaction.atomic(): # Here
animal = Animal.objects.all() # For "SELECT" query
print(animal) # Needed to run "SELECT" query
Animal(name='Dog').save() # For "INSERT" query
Animal.objects.filter(name="Dog").update(name="Cat") # For "UPDATE" query
Animal.objects.filter(name="Cat").delete() # For "DELETE" query
def __str__(self):
return self.first_name + " " + self.last_name
Run Code Online (Sandbox Code Playgroud)
而且,我还在“settings.py”中将'ATOMIC_REQUESTS': True设置为我的 PostgreSQL 设置,如下所示:
# "core/settings.py"
DATABASES = {
'default':{
'ENGINE':'django.db.backends.postgresql',
'NAME':'postgres',
'USER':'postgres',
'PASSWORD':'admin',
'HOST':'localhost',
'PORT':'5432',
'ATOMIC_REQUESTS': True, # Here
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我添加一个人来运行“Person”类中重写的“save()”,如下所示:
现在,在“BEGIN”和“COMMIT”查询之间,3个“SAVEPOINT”和3个“RELEASE SAVEPOINT”查询由“@transaction.atomic”装饰器运行,“with transaction.atomic():”和“ATOMIC_REQUESTS”:True和添加了2 个蓝色的“SELECT”查询,如下所示:
另外,再次使用PostgreSQL,我还通过下面的代码尝试了默认情况下是否将原子事务隐式用于视图。* “SELECT”、“INSERT”、“UPDATE”和“DELETE”查询由“views.py”上“test()”视图中的“Animal”类代码运行,如下所示:
# "store/views.py"
from django.http import HttpResponse
from .models import Animal
def test(request):
animal = Animal.objects.all() # For "SELECT" query
print(animal) # Needed to run "SELECT" query
Animal(name='Dog').save() # For "INSERT" query
Animal.objects.filter(name="Dog").update(name="Cat") # For "UPDATE" query
Animal.objects.filter(name="Cat").delete() # For "DELETE"
return HttpResponse("Test")
Run Code Online (Sandbox Code Playgroud)
并且,这是下面的“urls.py”:
# "store/urls.py"
from django.urls import path
from . import views
app_name = "store"
urlpatterns = [
path('test/', views.test, name="test"),
]
Run Code Online (Sandbox Code Playgroud)
然后,我打开url“http://localhost:8000/store/test/”来运行“test”视图,如下所示:
现在,在“BEGIN”和“COMMIT”查询之间,“test()”视图中的“Animal”类代码仅运行“DELETE”查询。因此,默认情况下,原子事务不会隐式用于视图。*下面这些日志是PostgreSQL的查询日志:
接下来,对于“test()”视图,我放置“@transaction.atomic”装饰器,如下所示:
# "store/views.py"
from django.http import HttpResponse
from .models import Animal
@transaction.atomic # Here
def test(request):
animal = Animal.objects.all() # For "SELECT" query
print(animal) # Needed to run "SELECT" query
Animal(name='Dog').save() # For "INSERT" query
Animal.objects.filter(name="Dog").update(name="Cat") # For "UPDATE" query
Animal.objects.filter(name="Cat").delete() # For "DELETE"
return HttpResponse("Test")
Run Code Online (Sandbox Code Playgroud)
或者,对于“test()”视图,我输入“with transaction.atomic():”,如下所示:
# "store/views.py"
from django.http import HttpResponse
from .models import Animal
def test(request):
with transaction.atomic(): # Here
animal = Animal.objects.all() # For "SELECT" query
print(animal) # Needed to run "SELECT" query
Animal(name='Dog').save() # For "INSERT" query
Animal.objects.filter(name="Dog").update(name="Cat") # For "UPDATE" query
Animal.objects.filter(name="Cat").delete() # For "DELETE"
return HttpResponse("Test")
Run Code Online (Sandbox Code Playgroud)
或者,对于“test()”视图,我将'ATOMIC_REQUESTS': True放入“settings.py”中的PostgreSQL 设置,如下所示:
# "core/settings.py"
DATABASES = {
'default':{
'ENGINE':'django.db.backends.postgresql',
'NAME':'postgres',
'USER':'postgres',
'PASSWORD':'admin',
'HOST':'localhost',
'PORT':'5432',
'ATOMIC_REQUESTS': True, # Here
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我打开url“http://localhost:8000/store/test/”来运行“test”视图,如下所示:
现在,在“BEGIN”和“COMMIT”查询之间,“SELECT”、“INSERT”、“UPDATE”和“DELETE”查询由“test()”视图中的“Animal”类代码运行。现在,原子事务可以工作了:
接下来,对于“test()”视图,我放置了“@transaction.atomic”装饰器和“with transaction.atomic():”,如下所示:
# "store/views.py"
from django.http import HttpResponse
from .models import Animal
@transaction.atomic # Here
def test(request):
with transaction.atomic(): # Here
animal = Animal.objects.all() # For "SELECT" query
print(animal) # Needed to run "SELECT" query
Animal(name='Dog').save() # For "INSERT" query
Animal.objects.filter(name="Dog").update(name="Cat") # For "UPDATE" query
Animal.objects.filter(name="Cat").delete() # For "DELETE"
return HttpResponse("Test")
Run Code Online (Sandbox Code Playgroud)
而且,我还在“settings.py”中将'ATOMIC_REQUESTS': True设置为我的 PostgreSQL 设置,如下所示:
# "core/settings.py"
DATABASES = {
'default':{
'ENGINE':'django.db.backends.postgresql',
'NAME':'postgres',
'USER':'postgres',
'PASSWORD':'admin',
'HOST':'localhost',
'PORT':'5432',
'ATOMIC_REQUESTS': True, # Here
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我打开url“http://localhost:8000/store/test/”来运行“test”视图,如下所示:
现在,在“BEGIN”和“COMMIT”查询之间,运行2 个“SAVEPOINT”和 2 个“RELEASE SAVEPOINT”查询,如下所示:
| 归档时间: |
|
| 查看次数: |
2836 次 |
| 最近记录: |