Issue: Required attribute for Fields
Author: mkosler
State: closed
Created: 2012-07-10 04:26:04

Newish to SQL so feel free to correct me if I can do this in some way already.

Is a field being not nullable the same as making the field required? I would figure this would be true, but doing some python shell experimenting, it seems that this is not true. I think adding a 'required' attribute to the base Field class would be nice. Throw an exception you attempt to use either `Model.create()` or `Model.save()` with an uninitialized required variable.


Yes, non-nullable is the same as required.  Not null means if you do not store something there, the database will complain.  Adding a required would be redundant.


Well, then I think there must be a bug, because like I said, when I do this in the python shell, it doesn't yell at me. This is the model I am using for this:

```
class User(BaseModel):
    username = CharField(unique = True)
    password = CharField(max_length = 40)
    email = CharField(unique = True)
    date_joined = DateField(default = datetime.date.today())
    website = CharField(null = True)
    logged_in = BooleanField()
    is_mod = BooleanField()
    is_admin = BooleanField()
```

BaseModel just sets the Meta class to the correct database. Here is what I run in the shell to show the issue:

```
>>> from models import *
>>> user = User.create(username = 'test')
>>> user.save() # redundant, but whatever
>>> print user.password
None
>>> user2 = User.get()
>>> print user2.username
test
>>> print user2.password

>>> 
```

From my understanding, the only field that should be allowed to be left blank is `website`, but I've clearly left every field besides username blank.

I am using flask-script to get shell access, via `python manage.py shell`. Here's all the other libraries I am using:

```
Flask==0.9
Flask-Script==0.3.3
Jinja2==2.6
WTForms==1.0.1
Werkzeug==0.8.3
argparse==1.2.1
passlib==1.6
peewee==0.9.9
wsgiref==0.1.2
```


It appears peewee is setting it to an empty string when no value is present (as opposed to letting it fall through to the database and raising an integrity error).  This is probably a bug...working on a test case


Hrm... I'm torn on this one.  Looking a little closer, it appears that Field() is wrapping up the value passed to the db.  It has the following check:

``` python

    def db_value(self, value):
        if (self.null and value is None):
            return None
        return self.column.db_value(value)
```

The column converts the value to a suitable type, e.g. VarCharColumn does `unicode(value or '')`.

I'm thinking that this behavior is acceptable.  The best I can say is its a gray area.  If you want to store NULLs then make the field nullable, otherwise an empty string (or "0", etc) will be put in to avoid the integrity error.


Then could we get a required attribute at some point? If I'm using the shell as my admin interface during development, I could easily pollute my DB with inconsistent data.


Grr... i keep waffling on this.

I think that the only acceptable answer is to allow NULL values to get sent back regardless, and let the integrity error happen if the field isn't null.  Working on a testcase and a patch.