为了清空一个数据库表,我使用以下的SQL查询:
TRUNCATE TABLE `books`
如何使用Django的模型和ORM截断表格?
我尝试过这个,但它并不起作用:
Book.objects.truncate()
为了清空一个数据库表,我使用以下的SQL查询:
TRUNCATE TABLE `books`
如何使用Django的模型和ORM截断表格?
我尝试过这个,但它并不起作用:
Book.objects.truncate()
使用 ORM,你最接近的方法是 Book.objects.all().delete()
。
但是有一些区别:truncate 可能更快,但 ORM 也会追踪外键引用并删除其他表中的对象。
您可以以快速且轻量的方式完成此操作,但不使用Django的ORM。您可以使用Django连接游标执行原始SQL:
from django.db import connection
cursor = connection.cursor()
cursor.execute("TRUNCATE TABLE `books`")
from django.db import connection
cursor = connection.cursor()
cursor.execute('TRUNCATE TABLE "{0}"'.format(MyModel._meta.db_table))
重要提示:这个方法对于涉及多个表的继承模型不适用!
除了Ned Batchelder的回答,参考Bernhard Kircher的评论:
在我的情况下,我需要使用Web应用程序清空一个非常大的数据库:
Book.objects.all().delete()
在开发SQLlite环境中,返回:
too many SQL variables
所以我添加了一个小的解决方法。它可能不是最整洁的,但至少在 Django 的 ORM 构建截断表选项之前可以使用:
countdata = Book.objects.all().count()
logger.debug("Before deleting: %s data records" % countdata)
while countdata > 0:
if countdata > 999:
objects_to_keep = Book.objects.all()[999:]
Book.objects.all().exclude(pk__in=objects_to_keep).delete()
countdata = Book.objects.all().count()
else:
Book.objects.all().delete()
countdata = Book.objects.all().count()
顺便提一下,我的一些代码是基于"Django Delete all but last five of queryset"。
我在意识到该答案已经被回答的情况下添加了这个,但希望这个补充能帮助其他人。
我知道这是一个很老的问题,并且这里有一些正确的答案,但我忍不住要分享最优雅和最快速的方法来完成这个问题的目的。
class Book(models.Model):
# Your Model Declaration
@classmethod
def truncate(cls):
with connection.cursor() as cursor:
cursor.execute('TRUNCATE TABLE {} CASCADE'.format(cls._meta.db_table))
现在,如果要从Book表中截断所有数据,只需调用以下命令:
Book.truncate()
由于它直接与数据库交互,因此执行速度比其他方法更快。
Book.objects.all().delete()
这段代码使用的是PosgreSQL方言。如果要使用标准SQL,请省略级联部分。
class TruncateManager(models.Manager):
def truncate(self, cascade=False):
appendix = " CASCADE;" if cascade else ";"
raw_sql = f"TRUNCATE TABLE {self.model._meta.db_table}{appendix}"
cursor = connection.cursor()
cursor.execute(raw_sql)
class Truncatable(models.Model):
class Meta:
abstract = True
objects = TruncateManager()
然后,您可以扩展Truncatable
来创建可截断的对象:
class Book(Truncatable):
...
这将允许您在所有继承自Truncatable的模型上调用truncate。
Book.objects.truncate()
python manage.py truncate --apps myapp --models Model1
,该表中的所有数据都将被删除!_model.objects.all().delete()
,这绝对不是截断操作。https://github.com/KhaledElAnsari/django-truncate/blob/master/django_truncate/management/commands/truncate.py - BrennanR对于我来说,要截断我的本地sqllite数据库,我最终使用python manage.py flush
。
我最初尝试的是迭代模型并逐个删除所有行:
models = [m for c in apps.get_app_configs() for m in c.get_models(include_auto_created=False)]
for m in models:
m.objects.all().delete()
但是由于我有保护外键,操作的成功取决于模型的顺序。
因此,我使用flush命令来截断我的本地测试数据库,并且它对我有效。 https://docs.djangoproject.com/en/3.0/ref/django-admin/#django-admin-flush
这并不是直接回答楼主的问题,但仍然是一个可能用来实现相同目的的解决方案 - 不同的方法。
好吧,由于某些奇怪的原因(在尝试使用其他答案中建议的RAW方法时),我无法截断我的Django数据库缓存表,直到我做了类似这样的事情:
import commands
cmd = ['psql', DATABASE, 'postgres', '-c', '"TRUNCATE %s;"' % TABLE]
commands.getstatusoutput(' '.join(cmd))
基本上,我不得不通过数据库的实用命令 - 在这种情况下是 psql
,因为我使用的是Postgres - 发出truncate
命令。因此,自动化命令行可以处理这些边角情况。
可能会节省其他人一些时间...