8

is there a way how to obtain last saved row in database while using peewee with all its attributes? Let's say I do this:

user = User.create(
    email = request.json['email'],
    nickname = request.json['nickname'],
    password = request.json['password'],
    salt = "salt"
)

But user.id is None and the only attributes I can get are those specified above. I could call select() method but isn't there there any faster way?

Thanks

skornos
  • 3,121
  • 1
  • 26
  • 30
  • For what it's worth, if User has a primary-key field for "id", the "id" will be populated automatically upon creation / save. – coleifer May 22 '18 at 19:28

3 Answers3

19
User.select().order_by(User.id.desc()).get()

This will get the last-created user assuming the IDs is an auto-incrementing integer (the default).

Or if you want to get e.g. last created customer (user), you can write it like this:

User.select().where(User.type == "customer").order_by(User.id.desc()).get()

If you want to get the last saved user, you need to add a timestamp to indicate when the user is saved.


Update:

Peewee also now supports RETURNING clause for Postgres database. You can add a RETURNING clause to any INSERT, UPDATE or DELETE query. Check out the docs:

Muhammad Shahbaz
  • 319
  • 1
  • 3
  • 10
coleifer
  • 24,887
  • 6
  • 60
  • 75
7

Instead of re-querying the DB, one alternative is the following:

u = User(email="..", nickname="..", password="..", salt="..")
u.save()

# at this point, peewee inserted the entry in the DB,
# and updated all relevant fields (including the ID).
# For example, you can do the following:

print "ID of last-created user: %d" % u.id

For complex, multi-threaded systems, I think this a better alternative.

reyammer
  • 194
  • 2
  • 7
  • 1
    Peewee also now supports `RETURNING` (postgres only), which works on INSERT, UPDATE and DELETE queries. [Docs here](http://docs.peewee-orm.com/en/latest/peewee/querying.html#returning-clause). – coleifer Jul 27 '15 at 22:21
1

I'm guessing your User model looks like this:

class User(Model):
    id = IntegerField(primary_key=True)
    email = TextField(unique=True)
    nickname = TextField()
    password = TextField()
    salt = TextField()

But peewee doesn't know how to handle autoincrementing fields unless you use its PrimaryKeyField class:

class User(Model):
    id = PrimaryKeyField()
    email = TextField(unique=True)
    nickname = TextField()
    password = TextField()
    salt = TextField()

This wasn't documented anywhere I could find. Source.

jtschoonhoven
  • 1,948
  • 1
  • 19
  • 16