要清空数据库表,我使用此 SQL 查询:
TRUNCATE TABLE `books`
如何使用 Django 模型和 ORM 截断表?
我已经尝试过这个,但它不起作用:
Book.objects.truncate()
使用 ORM 最接近的是
Book.objects.all().delete()
。
但也有区别:截断可能会更快,但 ORM 也会追踪外键引用并删除其他表中的对象。
您可以通过快速且轻量级的方式来完成此操作,但不能使用 Django 的 ORM。您可以使用 Django 连接游标执行原始 SQL:
from django.db import connection
cursor = connection.cursor()
cursor.execute("TRUNCATE TABLE `books`")
可以使用模型的_meta属性填写数据库表名:
from django.db import connection
cursor = connection.cursor()
cursor.execute('TRUNCATE TABLE "{0}"'.format(MyModel._meta.db_table))
重要:这不适用于继承模型,因为它们跨越多个表!
仅适用于 Postgres:对于外键限制,您可以使用
Truncate Cascade
,这也会截断所有相关表。
cursor.execute('TRUNCATE TABLE "{0}" CASCADE'.format(MyModel._meta.db_table))
除了 Ned Batchelder 的回答并参考 Bernhard Kircher 的评论:
就我而言,我需要使用网络应用程序清空一个非常大的数据库:
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删除查询集最后五个以外的所有内容”。
我在知道答案已经得到解答的情况下添加了此内容,但希望此添加对其他人有所帮助。
我知道这是一个非常古老的问题,这里也很少有正确的答案,但我无法抗拒自己分享最优雅和最快的方法来达到这个问题的目的。
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()
我还添加了一个使用级联的标志,该标志(危险区域)还将:“自动截断对任何指定表或由于 CASCADE 添加到组中的任何表具有外键引用的所有表.”,这显然更具破坏性,但将允许代码在原子事务内运行。
现在有一个库可以帮助您截断 Django 项目数据库中的特定表,它称为 django-truncate。
很简单,只需运行
python manage.py truncate --apps myapp --models Model1
,该表中的所有数据都将被删除!
对于我来说,要截断我的本地 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()
但是因为我有受保护的外键,操作的成功取决于模型的顺序。
所以,我正在使用 telush 命令来截断我的本地测试数据库,它对我有用 https://docs.djangoproject.com/en/3.0/ref/django-admin/#django-admin-flush
这并不能直接回答OP的问题,但仍然是一种可以用来实现相同目标的解决方案 - 不同。
好吧,由于一些奇怪的原因(在尝试使用这里其他答案中建议的RAW方法时),我未能截断我的Django数据库缓存表,直到我做了这样的事情:
import commands
cmd = ['psql', DATABASE, 'postgres', '-c', '"TRUNCATE %s;"' % TABLE]
commands.getstatusoutput(' '.join(cmd))
基本上,我不得不通过数据库的实用程序命令发出
truncate
命令 - 在本例中为 psql
,因为我使用的是 Postgres。因此,自动化命令行可能会处理此类极端情况。
可能会节省别人一些时间...