通过一个查询在其他字段中使用 self.id

发布于 12-28 18:06 字数 597 浏览 2 评论 0原文

诚然,这是一个与这个非常相似的问题 不过我之前问过,如果能得到答案就太好了。

我想通过使用主键填充另一个字段来创建实例。 Yuji Tomita 建议了一种使用两个查询的解决方案(顺便说一句,它工作得很好),但我想知道是否可以仅使用一个查询来完成该任务。

富田雄二的解决方案:

def save(self, *args, **kwargs):
    add = not self.pk
    super(MyModel, self).save(*args, **kwargs)
    if add:
        self.identification = str(self.id)
        kwargs['force_insert'] = False # create() uses this, which causes error.
        super(MyModel, self).save(*args, **kwargs)

提前致谢。

Admittedly, this is a very similar question to this one I asked before, however, it would be very nice to have an answer to it.

I want to create an instance by using the primary key to populate another field. Yuji Tomita suggested a solution using two queries (which by the way, it works perfectly fine) but I want to know if it's possible to accomplish that using only one query.

Yuji Tomita's solution:

def save(self, *args, **kwargs):
    add = not self.pk
    super(MyModel, self).save(*args, **kwargs)
    if add:
        self.identification = str(self.id)
        kwargs['force_insert'] = False # create() uses this, which causes error.
        super(MyModel, self).save(*args, **kwargs)

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半世晨晓2025-01-04 18:06:29

如果您的主键是自动递增的整数,则可以通过从 db shell 运行 SELECT MAX(id) FROM myTable 来计算下一个键;或者在 django 中:

from django.db.models import Max
next_key = MyTable.objects.aggregate(next=Max('id'))['next']+1

这种方法的问题是你必须实现行锁定;否则另一个进程可能会添加到数据库 - 获取下一个 ID 值,这将导致您的代码给出 IntegrityError 异常;它并不能解决您的“两个查询”挑战。

更好的解决方案是使用非顺序主键。这通常是 UUID。在 MySQL 中,您可以使用 UUID() 函数作为主键。这(合理地)保证了不会发生冲突并且是唯一的。

在 Django 中,没有对 UUID 字段的官方支持(补丁 已提交),但有很多 示例 您可以使用。

如果您走这条路线,那么您可以在任何时候生成主键,然后将其分配给模型,而无需执行查询。

If your primary key is an automatically incrementing integer, you can calculate the next key by running SELECT MAX(id) FROM myTable from the db shell; or in django:

from django.db.models import Max
next_key = MyTable.objects.aggregate(next=Max('id'))['next']+1

The problem with this approach is that you have to implement row locking; otherwise another process might add to the database - taking the next ID value, which will cause your code to give an IntegrityError exception; and it doesn't solve your 'two query' challenge.

A better solution is to use non-sequential primary keys. This is usually a UUID. In MySQL you can use the UUID() function as your primary key. This guarantees (reasonably) to not have collisions and be unique.

In Django there is no official support for UUID fields (a patch has been submitted), but there are lots of examples you can use.

If you go this route then you can generate at any point a primary key and then assign it to the model without executing a query.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文