web-dev-qa-db-ja.com

SQLAlchemyで「nullable = False」はどのように機能しますか

SQLAlchemyドキュメントから:

nullable-デフォルトのTrueに設定されている場合、列がNULLを許可するようにレンダリングされることを示します。それ以外の場合は、NOT NULLとしてレンダリングされます。このパラメーターは、CREATE TABLEステートメントを発行するときにのみ使用されます。

設定を考えたnullable=True列の場合、基本的にその列が必要になります。例えば:

class Location(db.Model):
    __tablename__ = 'locations'
    id = db.Column(db.Integer, primary_key=True)
    latitude = db.Column(db.String(50), nullable=False)
    ...

しかし、緯度フィールドなしでLocationインスタンスを作成しても、エラーは発生しません!

Python 2.7.8 (default, Oct 19 2014, 16:02:00)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.54)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

>>> Location(latitude=None)
<app.models.Location object at 0x10dce9dd0>

何が起こっている?

14
Ben Sandler

あなたが参照するドキュメントは問題を説明しています:

このパラメーターは、CREATE TABLEステートメントを発行するときにのみ使用されます。

最初にnullable=Falseなしでデータベースを作成した場合(またはSQLAlchemyとは別に、その列にNOT NULLなしで作成した場合)、データベースcolumnは作成されませんその制約情報があります。この情報は、作成または挿入している特定のインスタンスではなく、データベース列を参照して存在します。

テーブルを再構築せずにSQLAlchemyテーブルの作成を変更すると、変更が反映されません。コメント内のリンクで説明されているように、SQLAlchemyはそのレベルで検証を行っていません(@validatesデコレータなどの何かを使用する必要があります)。

15
dwanderson

最初にLocationインスタンスを作成してデータベースにコミットしたときに、「null可能」がTrueに設定されましたか?もしそうなら、sqlalchemyはその後にnull許容パラメータを「False」にリセットすることを許可しません。 Alembicを使用してデータベースを移行する必要があります

3
Mark Pham