Django BigInteger自动增量字段作为主键?

时间:2021-10-03 16:48:53

I'm currently building a project which involves a lot of collective intelligence. Every user visiting the web site gets created a unique profile and their data is later used to calculate best matches for themselves and other users.

我目前正在建立一个涉及大量集体智慧的项目。访问该网站的每个用户都会创建一个独特的配置文件,他们的数据稍后将用于为自己和其他用户计算最佳匹配。

By default, Django creates an INT(11) id field to handle models primary keys. I'm concerned with this being overflown very quickly (i.e. ~2.4b devices visiting the page without prior cookie set up). How can I change it to be represented as BIGINT in MySQL and long() inside Django itself?

默认情况下,Django创建一个INT(11)id字段来处理模型主键。我担心这种情况很快就会溢出(即〜2.4b设备访问该页面而没有事先设置cookie)。如何将其更改为在MySQL中表示为BIGINT,在Django本身中表示为long()?

I've found I could do the following (http://docs.djangoproject.com/en/dev/ref/models/fields/#bigintegerfield):

我发现我可以执行以下操作(http://docs.djangoproject.com/en/dev/ref/models/fields/#bigintegerfield):

class MyProfile(models.Model):
    id = BigIntegerField(primary_key=True)

But is there a way to make it autoincrement, like usual id fields? Additionally, can I make it unsigned so that I get more space to fill in?

但有没有办法让它像通常的id字段一样自动增量?另外,我可以将它设为无符号,以便我可以填充更多空间吗?

Thanks!

谢谢!

6 个解决方案

#1


8  

Django now has a BigAutoField built in if you are using Django 1.10:

如果您使用Django 1.10,Django现在内置了BigAutoField:

https://docs.djangoproject.com/en/1.10/ref/models/fields/#bigautofield

https://docs.djangoproject.com/en/1.10/ref/models/fields/#bigautofield

#2


16  

Inspired by lfagundes but with a small but important correction:

受到lfagundes的启发,但有一个小而重要的修正:

class BigAutoField(fields.AutoField):
    def db_type(self, connection):  # pylint: disable=W0621
        if 'mysql' in connection.__class__.__module__:
            return 'bigint AUTO_INCREMENT'
        return super(BigAutoField, self).db_type(connection)

add_introspection_rules([], [r"^a\.b\.c\.BigAutoField"])

Notice instead of extending BigIntegerField, I am extending AutoField. This is an important distinction. With AutoField, Django will retrieve the AUTO INCREMENTed id from the database, whereas BigInteger will not.

请注意,我没有扩展BigIntegerField,而是扩展了AutoField。这是一个重要的区别。使用AutoField,Django将从数据库中检索AUTO INCREMENTed id,而BigInteger则不会。

One concern when changing from BigIntegerField to AutoField was the casting of the data to an int in AutoField.

从BigIntegerField更改为AutoField时的一个问题是将数据转换为AutoField中的int。

Notice from Django's AutoField:

来自Django的AutoField的通知:

def to_python(self, value):
    if value is None:
        return value
    try:
        return int(value)
    except (TypeError, ValueError):
        msg = self.error_messages['invalid'] % str(value)
        raise exceptions.ValidationError(msg)

and

def get_prep_value(self, value):
    if value is None:
        return None
    return int(value)

It turns out this is OK, as verified in a python shell:

事实证明这是可以的,正如在python shell中验证的那样:

>>> l2 = 99999999999999999999999999999
>>> type(l2)
<type 'long'>
>>> int(l2)
99999999999999999999999999999L
>>> type(l2)
<type 'long'>
>>> type(int(l2))
<type 'long'>

In other words, casting to an int will not truncate the number, nor will it change the underlying type.

换句话说,转换为int不会截断数字,也不会更改基础类型。

#3


13  

NOTE: This answer as modified, according to Larry's code. Previous solution extended fields.BigIntegerField, but better to extend fields.AutoField

注意:根据Larry的代码,这个答案被修改了。以前的解决方案扩展了fields.BigIntegerField,但更好地扩展fields.AutoField

I had the same problem and solved with following code:

我有同样的问题,并通过以下代码解决:

from django.db.models import fields
from south.modelsinspector import add_introspection_rules

class BigAutoField(fields.AutoField):
    def db_type(self, connection):
        if 'mysql' in connection.__class__.__module__:
            return 'bigint AUTO_INCREMENT'
        return super(BigAutoField, self).db_type(connection)

add_introspection_rules([], ["^MYAPP\.fields\.BigAutoField"])

Apparently this is working fine with south migrations.

显然这对南方迁移来说很好。

#4


6  

You could alter the table afterwards. That may be a better solution.

之后您可以更改表格。这可能是一个更好的解决方案。

#5


3  

As stated before you could alter the table afterwards. That is a good solution.

如前所述,您之后可以更改表格。这是一个很好的解决方案。

To do that without forgetting, you can create a management module under your application package and use the post_syncdb signal.

要做到这一点而不忘记,您可以在应用程序包下创建一个管理模块并使用post_syncdb信号。

https://docs.djangoproject.com/en/dev/ref/signals/#post-syncdb

https://docs.djangoproject.com/en/dev/ref/signals/#post-syncdb

This can cause django-admin.py flush to fail. But it is still the best alternative I know.

这可能导致django-admin.py刷新失败。但它仍然是我所知道的最佳选择。

#6


1  

I also had the same problem. Looks like there is no support for BigInteger auto fields in django.

我也有同样的问题。看起来django中不支持BigInteger自动字段。

I've tried to create some custom field BigIntegerAutoField but I faced a problem with south migration system (south couldn't create sequence for my field).

我试图创建一些自定义字段BigIntegerAutoField但是我遇到了南迁移系统的问题(南方无法为我的字段创建序列)。

After giving a try couple of different approaches I decided to follow Matthew's advice and do alter table (e.g. ALTER TABLE table_name ALTER COLUMN id TYPE bigint; in postgre)

在尝试了几种不同的方法后,我决定遵循马修的建议并改变表格(例如ALTER TABLE table_name ALTER COLUMN id TYPE bigint;在postgre中)

Would be great to have solution supported by django (like built in BigIntegerAutoField) and south.

很高兴有django支持的解决方案(如内置BigIntegerAutoField)和南方。

#1


8  

Django now has a BigAutoField built in if you are using Django 1.10:

如果您使用Django 1.10,Django现在内置了BigAutoField:

https://docs.djangoproject.com/en/1.10/ref/models/fields/#bigautofield

https://docs.djangoproject.com/en/1.10/ref/models/fields/#bigautofield

#2


16  

Inspired by lfagundes but with a small but important correction:

受到lfagundes的启发,但有一个小而重要的修正:

class BigAutoField(fields.AutoField):
    def db_type(self, connection):  # pylint: disable=W0621
        if 'mysql' in connection.__class__.__module__:
            return 'bigint AUTO_INCREMENT'
        return super(BigAutoField, self).db_type(connection)

add_introspection_rules([], [r"^a\.b\.c\.BigAutoField"])

Notice instead of extending BigIntegerField, I am extending AutoField. This is an important distinction. With AutoField, Django will retrieve the AUTO INCREMENTed id from the database, whereas BigInteger will not.

请注意,我没有扩展BigIntegerField,而是扩展了AutoField。这是一个重要的区别。使用AutoField,Django将从数据库中检索AUTO INCREMENTed id,而BigInteger则不会。

One concern when changing from BigIntegerField to AutoField was the casting of the data to an int in AutoField.

从BigIntegerField更改为AutoField时的一个问题是将数据转换为AutoField中的int。

Notice from Django's AutoField:

来自Django的AutoField的通知:

def to_python(self, value):
    if value is None:
        return value
    try:
        return int(value)
    except (TypeError, ValueError):
        msg = self.error_messages['invalid'] % str(value)
        raise exceptions.ValidationError(msg)

and

def get_prep_value(self, value):
    if value is None:
        return None
    return int(value)

It turns out this is OK, as verified in a python shell:

事实证明这是可以的,正如在python shell中验证的那样:

>>> l2 = 99999999999999999999999999999
>>> type(l2)
<type 'long'>
>>> int(l2)
99999999999999999999999999999L
>>> type(l2)
<type 'long'>
>>> type(int(l2))
<type 'long'>

In other words, casting to an int will not truncate the number, nor will it change the underlying type.

换句话说,转换为int不会截断数字,也不会更改基础类型。

#3


13  

NOTE: This answer as modified, according to Larry's code. Previous solution extended fields.BigIntegerField, but better to extend fields.AutoField

注意:根据Larry的代码,这个答案被修改了。以前的解决方案扩展了fields.BigIntegerField,但更好地扩展fields.AutoField

I had the same problem and solved with following code:

我有同样的问题,并通过以下代码解决:

from django.db.models import fields
from south.modelsinspector import add_introspection_rules

class BigAutoField(fields.AutoField):
    def db_type(self, connection):
        if 'mysql' in connection.__class__.__module__:
            return 'bigint AUTO_INCREMENT'
        return super(BigAutoField, self).db_type(connection)

add_introspection_rules([], ["^MYAPP\.fields\.BigAutoField"])

Apparently this is working fine with south migrations.

显然这对南方迁移来说很好。

#4


6  

You could alter the table afterwards. That may be a better solution.

之后您可以更改表格。这可能是一个更好的解决方案。

#5


3  

As stated before you could alter the table afterwards. That is a good solution.

如前所述,您之后可以更改表格。这是一个很好的解决方案。

To do that without forgetting, you can create a management module under your application package and use the post_syncdb signal.

要做到这一点而不忘记,您可以在应用程序包下创建一个管理模块并使用post_syncdb信号。

https://docs.djangoproject.com/en/dev/ref/signals/#post-syncdb

https://docs.djangoproject.com/en/dev/ref/signals/#post-syncdb

This can cause django-admin.py flush to fail. But it is still the best alternative I know.

这可能导致django-admin.py刷新失败。但它仍然是我所知道的最佳选择。

#6


1  

I also had the same problem. Looks like there is no support for BigInteger auto fields in django.

我也有同样的问题。看起来django中不支持BigInteger自动字段。

I've tried to create some custom field BigIntegerAutoField but I faced a problem with south migration system (south couldn't create sequence for my field).

我试图创建一些自定义字段BigIntegerAutoField但是我遇到了南迁移系统的问题(南方无法为我的字段创建序列)。

After giving a try couple of different approaches I decided to follow Matthew's advice and do alter table (e.g. ALTER TABLE table_name ALTER COLUMN id TYPE bigint; in postgre)

在尝试了几种不同的方法后,我决定遵循马修的建议并改变表格(例如ALTER TABLE table_name ALTER COLUMN id TYPE bigint;在postgre中)

Would be great to have solution supported by django (like built in BigIntegerAutoField) and south.

很高兴有django支持的解决方案(如内置BigIntegerAutoField)和南方。