1

I'am facing whith strange Peewee's model behaviour.

For my model (database PostgreSQL):

class Car(BaseTable):
   id = UUIDField(primary_key=True, unique=True, default=uuid4)
   user = ForeignKeyField(SocialUser)
   vendor = CharField(max_length=30)
   model = CharField(max_length=30)
   colour = CharField(max_length=30)
   number = CharField(max_length=30)
   registered_date = DateTimeField(default=datetime.datetime.now)

I'am trying to update some Fields this way:

with database.atomic():
    car, created = Car.get_or_create(user=record['user'],
                                     number=record['number'],
                                     defaults={'vendor': record['vendor'],
                                               'model': record['model'],
                                               'colour': record['colour']
                                               })

    if not created:
        print(car.vendor, type(car.vendor), len(car.vendor))
        print(record['vendor'], type(record['vendor']), len(record['vendor']))
        car.vendor = record['vendor'],
        car.model = record['model'],
        car.colour = record['colour']
        print('-------------------------------')
        print(type(car.vendor), len(car.vendor))
        print(type(record['vendor']), len(record['vendor']))
        car.save()

For these arguments:

record['user'] = '3dba2da7-f005-4806-888c-167669a984b0'
record['number'] = 'е123кх777rus'
record['vendor'] = 'Hyundai'
record['model'] = 'Creta'
record['colour'] = 'Green'

Result in console:

Hyundai <class 'str'> 7  
Hyundai <class 'str'> 7
------------------------------- 
('Hyundai',) <class 'tuple'> 1  
Hyundai <class 'str'> 7

Result in database:

                  id                  |               user_id                |   vendor    |   model    | colour |    number    |      registered_date       
 28dfdfe6-2230-4d90-94f5-27b2946e8dc6 | 3dba2da7-f005-4806-888c-167669a984b0 | ('Hyndai',) | ('Creta',) | Green  | е123кх777rus | 2021-06-15 09:58:06.583585

However, if I'am using this way:

with database.atomic():
    car, created = Car.get_or_create(user=record['user'],
                                     number=record['number'],
                                     defaults={'vendor': record['vendor'],
                                               'model': record['model'],
                                               'colour': record['colour']
                                               })

    if not created:
        Car.update(vendor=record['vendor'],
                   model=record['model'],
                   colour=record['colour'])\
            .where(Car.id == car.id)\
            .execute()

This works propertly and no tuples in instance and in database.

Could You explain me why?

  • I added an integration test for get_or_create() with defaults, and it is all working correctly, so I suspect a bug in your code: https://github.com/coleifer/peewee/commit/d85590de8a251893d0712bd9ab99ea732abbc7f3 – coleifer Jun 15 '21 at 14:11
  • 1
    Thank You! But problem is not in get_or_greate. It's works propertly. Bug raises when I'am try to modify values in fields of the instance after get_or_create. If I'am use Car.update it work fine with same items of dictionary "record". – Максим Виговский Jun 15 '21 at 15:28
  • @МаксимВиговский I am seeing the same behavior. Thank you for reporting this. – Carl Parker May 10 '22 at 18:35

0 Answers0