1

DjangoアプリのHerokuでpostgresqlを使用しています。自分の投稿にコメントを付けようとすると、このエラーが発生することがあります(これも、常にではない場合があります)。

エラーにもかかわらず、コメントは保存されますが、save()に続くすべてのコードは実行されません。

ただし、この問題はpostgresqlでのみ発生します。sqliteを使用しているローカルホストでは、すべてが正常に機能します。

この理由はわかりません。

これが私のモデルの様子です

class Comment(models.Model):
    post = models.ForeignKey(post)
    date = models.DateTimeField(auto_now_add=True)
    comment = models.TextField()
    comment_user = models.ForeignKey(User)

それが私のコメントモデルのようです。コメントにmax_lengthを追加しなかったからですか?これがトレースバックです

DatabaseError at /post/114/
value too long for type character varying(10)
Request Method: POST
Request URL:    http://www.mysite.com/post/114/
Django Version: 1.4.1
Exception Type: DatabaseError
Exception Value:    
value too long for type character varying(10)
Exception Location: /app/.heroku/venv/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py in execute, line 52
Python Executable:  /app/.heroku/venv/bin/python2.7
Python Version: 2.7.2
Python Path:    
['/app',
 '/app/.heroku/venv/bin',
 '/app/.heroku/venv/lib/python2.7/site-packages/pip-1.1-py2.7.egg',
 '/app/.heroku/venv/lib/python2.7/site-packages/distribute-0.6.31-py2.7.egg',
 '/app',
 '/app/.heroku/venv/lib/python27.zip',
 '/app/.heroku/venv/lib/python2.7',
 '/app/.heroku/venv/lib/python2.7/plat-linux2',
 '/app/.heroku/venv/lib/python2.7/lib-tk',
 '/app/.heroku/venv/lib/python2.7/lib-old',
 '/app/.heroku/venv/lib/python2.7/lib-dynload',
 '/usr/local/lib/python2.7',
 '/usr/local/lib/python2.7/plat-linux2',
 '/usr/local/lib/python2.7/lib-tk',
 '/app/.heroku/venv/lib/python2.7/site-packages',
 '/app/.heroku/venv/lib/python2.7/site-packages/PIL']
Server time:    Wed, 5 Dec 2012 20:41:39 -0600
4

2 に答える 2

5

Djangoのパーツについてはお役に立てません(申し訳ありません)ので、PostgreSQLについてお話しします。

アプリケーションのどこかにvarchar(10)列があり、その中に10文字より長いものを入れようとしている場合、おそらくどこかに検証がありません。SQLiteは列のサイズを無視し、サイズ制限のないvarchar(n)ものとして扱います。textしたがって、SQLiteで次のようなことができます。

sqlite> create table t (s varchar(5));
sqlite> insert into t (s) values ('Where is pancakes house?');
sqlite> select * from t;
s
where is pancakes house?

苦情はありません。同様に、SQLiteを使用すると、数値列に文字列を挿入するなどのばかげた処理を実行できます。

これはあなたがする必要があることです:

  1. PostgreSQLの上にデプロイする場合は、SQLiteでの開発を停止してください。PostgreSQLをローカルにインストールし、その上で開発します。Herokuで使用するのと同じバージョンのPostgreSQLをインストールすることもできます。データベース間にはさまざまな違いがあり、頭痛の種になります。この小さなフィールドサイズの問題は、データベース間の問題を簡単に紹介するだけです。
  2. varchar(n)PostgreSQLでの使用をやめ、を使用してtextください。サイズを制限する必要があるという厳しい要件がない限り、PostgreSQLでサイズが制限された文字列列を使用しても意味がありません。細かいマニュアルから:

    短い文字列(最大126バイト)のストレージ要件は、1バイトに実際の文字列を加えたもので、文字の場合はスペースパディングが含まれます。長い文字列には、1ではなく4バイトのオーバーヘッドがあります。長い文字列はシステムによって自動的に圧縮されるため、ディスク上の物理的な要件は少なくなる可能性があります。[...]特定の上限のない長い文字列を保存する場合は、text... を使用します。

    ヒント:ブランクパッドタイプを使用する場合のストレージスペースの増加と、長さに制約のある列に格納する場合の長さをチェックするためのCPUサイクルの追加を除けば、これら3つのタイプの間にパフォーマンスの違いはありません。他のいくつcharacter(n)かのデータベースシステムにはパフォーマンス上の利点がありますが、PostgreSQLにはそのような利点はありません。実際character(n)、追加のストレージコストのため、通常は3つの中で最も低速です。ほとんどの場合text、またはcharacter varying代わりに使用する必要があります。

    したがって、必要がない限り、従来のPostgreSQLcharやPostgreSQLを気にせずvarcharに、を使用してtextください。

  3. 受信データの検証を開始して、サイズや形式の制約に違反していないことを確認します。

varchar(n)textすぐにからに切り替えて、PostgreSQLを起動して実行している間SQLiteで作業を続けることができます。両方のデータベースは無制限の長さの文字列に満足しtext、この簡単な修正で当面の問題を乗り越えることができます。次に、できるだけ早く開発環境をPostgreSQLに切り替えて、コードが本番環境に移行する前にこのような問題をキャッチできるようにします。

于 2012-12-06T04:14:32.083 に答える
1

その理由は、PostgreSQLが実際にデータの長さをフィールドのサイズと照合し、大きすぎる場合はエラーを出すのに対し、SQLiteは指定されたフィールドサイズを完全に無視し、MySQLはデータをサイレントに切り捨てて取り返しのつかないほど破壊するためです。フィールドを大きくします。

于 2012-12-06T02:50:23.927 に答える