2

この命令を使用して、モデルのデータを Django にダンプしようとすると:

python manage.py dumpdata app> temp_data.json

次のエラーが発生します。

Error: One or more models did not validate:
asset.authpermission: "codename": CharField cannot have a "max_length" greater than 255 when using "unique=True".
asset.djangocontenttype: "app_label": CharField cannot have a "max_length" greater than 255 when using "unique=True".
asset.djangocontenttype: "model": CharField cannot have a "max_length" greater than 255 when using "unique=True".

問題は、これらのテーブルが django によって自動生成されることです。さらに、データベース (mysql) をチェックインしたところ、フィールドは varchar(100) です。

どうしたの ?

4

2 に答える 2

6

それらのテーブルはmanage.py inspectdb権利によって生成されますか? その後、実際に生成されたモデルに django 独自のモデルを含める必要はありません。authdjango、 でadmin始まるモデルを削除するだけsiteです。

対応する contrib アプリを INSTALLED_APPS 設定に含めるだけで、エラーはなくなります。

于 2011-08-11T16:00:57.917 に答える
3

Django は、ダンプを許可する前に、データベース バックエンドが許可するものに対してスキーマを検証しようとしています。問題はこれです:

"unique=True" を使用する場合、CharField の "max_length" を 255 より大きくすることはできません。

あなたが経験している問題はこれです: SQL にCharField変換さVARCHARれます - それがどこmax_lengthに変換されている場合は、最大長を設定します。VARCHAR(X)X

MyISAM ではないテーブルの場合、MySQL は255CharField. これは、TextFieldどれが SQL に変換されるかも除外しますTEXT

インデックス作成に関する MySQL ドキュメントはかなり包括的です。ドキュメントは問題のCREATE INDEX核心にあなたを導きます:

FULLTEXT インデックスは MyISAM テーブルでのみサポートされており、CHAR、VARCHAR、および TEXT カラムのみを含めることができます。インデックスは常に列全体に対して行われます。列プレフィックスのインデックス作成はサポートされておらず、指定されている場合、プレフィックスの長さは無視されます。操作の詳細については、「11.9 全文検索機能」を参照してください。

つまり、ストレージ形式として MyISAM を使用していない限り、これを行うことはできません。

これが設計上の問題であるかどうかについては、どちらの方法でも議論があります。一方で、このような大量のデータを大量のテキストとしてインデックス化する必要がある場合は、それについてもっと慎重に考える必要があると主張することもできます。一方で、255 という制限は恣意的な選択であると主張することもできます。なぜ 300 ではなく 255 なのか? それとも200?私は

私はちょうどこの問題を自分で思いつきました。unique=True解決策は、が実際に必要かどうかを尋ねてから、max_length本当にそれほど長くする必要があるかどうかを判断することです。私の場合、128 文字の長さの sha512 出力を保存していたので、フィールドのサイズを適切に変更しました。

ただし、一意の長いデータが必要な場合は、モデルsave()メソッドをオーバーライドすることで、これを自分で強制できます。実際にやりたいことは、モデルのデータをスキーマに対して検証するためにfull_clean呼び出されるメソッドをオーバーライドし、オーバーライドされたメソッドにそれを呼び出すことです。そうすれば、直接保存するか、フォームで呼び出すかに関係なく、一意性制約が発生します。django.forms.*saveis_valid()

もう 1 つのオプションは、MyISAM に切り替えるか、postgres を使用することです。

于 2011-08-11T15:47:22.557 に答える