私は現在、多くの集団的知性を含むプロジェクトを構築しています。 Webサイトにアクセスするすべてのユーザーは一意のプロファイルを作成され、それらのデータは後で自分自身と他のユーザーの最適な一致を計算するために使用されます。
デフォルトでは、Djangoはモデルの主キーを処理するためにINT(11)id
フィールドを作成します。これが非常に迅速にオーバーフローすることを懸念しています(つまり、約24億台のデバイスが事前にCookieが設定されていないページ)。MySQLでBIGINTとして表され、Django自体の内部でlong()として表されるように変更するにはどうすればよいですか?
次のことができることがわかりました( http://docs.djangoproject.com/en/dev/ref/models/fields/#bigintegerfield ):
class MyProfile(models.Model):
id = BigIntegerField(primary_key=True)
しかし、通常のid
フィールドのように、自動インクリメントする方法はありますか?さらに、それを署名なしにして、記入するスペースを増やすことはできますか?
ありがとう!
Django 1.10:を使用している場合、DjangoにはBigAutoFieldが組み込まれています。
https://docs.djangoproject.com/en/1.10/ref/models/fields/#bigautofield
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"])
BigIntegerFieldを拡張する代わりに、AutoFieldを拡張していることに注意してください。これは重要な違いです。 AutoFieldを使用すると、DjangoはデータベースからAUTOINCREMENTed IDを取得しますが、BigIntegerは取得しません。
BigIntegerFieldからAutoFieldに変更する際の1つの懸念は、AutoFieldのintへのデータのキャストでした。
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)
そして
def get_prep_value(self, value):
if value is None:
return None
return int(value)
python Shell:
>>> l2 = 99999999999999999999999999999
>>> type(l2)
<type 'long'>
>>> int(l2)
99999999999999999999999999999L
>>> type(l2)
<type 'long'>
>>> type(int(l2))
<type 'long'>
つまり、intにキャストしても、数値が切り捨てられたり、基になる型が変更されたりすることはありません。
注:この回答は、ラリーのコードに従って変更されたものです。以前のソリューションはfields.BigIntegerFieldを拡張しましたが、fields.AutoFieldを拡張する方が適切です
私は同じ問題を抱えていて、次のコードで解決しました:
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"])
どうやらこれは南の移行でうまく機能しています。
後でテーブルを変更できます。それはより良い解決策かもしれません。
前に述べたように、後でテーブルを変更できます。それは良い解決策です。
これを忘れずに行うには、アプリケーションパッケージの下に管理モジュールを作成し、post_syncdbシグナルを使用します。
https://docs.djangoproject.com/en/dev/ref/signals/#post-syncdb
これにより、Django-admin.pyフラッシュが失敗する可能性があります。しかし、それでも私が知っている最良の選択肢です。
私も同じ問題を抱えていました。 DjangoではBigInteger自動フィールドがサポートされていないようです。
カスタムフィールドBigIntegerAutoFieldを作成しようとしましたが、南の移行システムで問題が発生しました(南はフィールドのシーケンスを作成できませんでした)。
いくつかの異なるアプローチを試した後、私はマシューのアドバイスに従い、テーブルを変更することにしました(例:ALTER TABLE table_name ALTER COLUMN id TYPE bigint;
postgre)
Django(BigIntegerAutoFieldに組み込まれているような)とsouthでソリューションがサポートされていると便利です。