Issue: Model create() and save() behavior
Author: changyuheng
State: closed
Created: 2016-09-06 20:31:26

Hi guys. I know this has been discussed in #651 but I still have some things want you guys to know.

[After inserting a new record by creating, we'll get an instance from return](http://docs.peewee-orm.com/en/latest/peewee/api.html#Model.create). No offense but I think intuitively this instance should be bound to the just created record. But it seemed like not.

Say I give some values to create a new record without giving the auto-increment primary key, then get the returned instance. If I modify the value on the instance and `.save()` again. It should update the current record. But it actually tries to create a new one.

Here's the test code:

``` py
from datetime import datetime
from peewee import Model, DateTimeField, ForeignKeyField, IntegerField, TextField, BooleanField, FloatField
from playhouse.sqlite_ext import SqliteExtDatabase
import json
import os


class MySqliteExtDatabase(SqliteExtDatabase):

    def sequence_exists(self, seq):
        super().sequence_exists(seq)

    def initialize_connection(self, conn):
        self.execute_sql('PRAGMA foreign_keys=ON;')

    def get_pragma(self, pragma):
        return next(self.execute_sql('PRAGMA ' + pragma + ';'))[0]

    def set_pragma(self, expression):
        self.execute_sql('PRAGMA ' + expression + ';')

    def get_version(self):
        return self.get_pragma('user_version')

    def set_version(self, version):
        self.set_pragma('user_version=' + str(version))


database = MySqliteExtDatabase(None, journal_mode='WAL')


class BaseModel(Model):
    id = IntegerField(primary_key=True)
    created_date = DateTimeField(index=True, default=datetime.utcnow)

    class Meta:
        database = database
        order_by = ('-created_date',)


class Settings(BaseModel):
    key = TextField(index=True)
    value = TextField(null=True)


class UniqSettings(BaseModel):
    key = TextField(unique=True)
    value = TextField(null=True)


def main():
    database_file = 'example.db'
    database.init(database_file)
    database.create_tables([Settings, UniqSettings], safe=True)

    setting = Settings.create(key='foo', value='bar')
    print('dumping Settings:')
    os.system('sqlite3 {} ".dump {}"'.format(database_file, 'settings'))

    setting.value = 'baz'
    setting.save()
    print('dumping Settings:')
    os.system('sqlite3 {} ".dump {}"'.format(database_file, 'settings'))

    setting.id = 1
    setting.save()
    print('dumping Settings:')
    os.system('sqlite3 {} ".dump {}"'.format(database_file, 'settings'))

    uniq_setting = UniqSettings.create(key='qux', value='quux')
    print('dumping UniqSettings:')
    os.system('sqlite3 {} ".dump {}"'.format(database_file, 'uniqsettings'))

    uniq_setting.value = 'corge'
    try:
        uniq_setting.save()
    except Exception as e:
        print(str(e))
    print('dumping UniqSettings:')
    os.system('sqlite3 {} ".dump {}"'.format(database_file, 'uniqsettings'))

    uniq_setting.id = 1
    uniq_setting.save()
    print('dumping UniqSettings:')
    os.system('sqlite3 {} ".dump {}"'.format(database_file, 'uniqsettings'))


if __name__ == '__main__':
    main()
```


Using IntegerField(primary _key=True) is not an auto-incrementing id. It happens to work due to the quirks of SQLite, but the semantics as far as peewee is concerned, are not autoincrement. You should use PrimaryKeyField instead.


http://docs.peewee-orm.com/en/latest/peewee/models.html#manually-specifying-primary-keys


You're right. I didn't use the library right. I'll close this issue. Thank you!


Well, I'm not happy about being right, since it means I made a confusing API in this case. I'll try and add some more visible docs around this behavior.