Updating database version
Please verify that this bug has NOT been raised before.
- [x] I checked and didn't find a similar issue
Describe the bug*
I updated to 1.1.2 recently and am currently using postgres v13 in my yml. I see the newest yml is running v17 and want to update my database.
I have tried a few times to try to restore running fresh containers running v17 and importing the json from my export, but it's not working for me and I am getting an error.
The database is empty before I start the import, as in, I can't even log in since there are no users. The error seems to be related to duplicate keys for a user.
Should import-records work when trying to update the database like this? I believe it should since it is database agnostic.
Is there a best way to do this?
Steps to Reproduce
Create new containers with empty v17 db
docker compose run --rm inventree-server invoke update
docker compose run inventree-server invoke import-records -c -f data/backup/data.json
unable to finish
Expected behaviour
The json import to work
Deployment Method
Docker
Version Information
1.1.2
Try to reproduce on the demo site
I did not try to reproduce
Is the bug reproducible on the demo site?
Not reproducible
Relevant log output
Traceback (most recent call last):
File "/root/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 89, in _execute
return self.cursor.execute(sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/.local/lib/python3.11/site-packages/psycopg/cursor.py", line 97, in execute
raise ex.with_traceback(None)
psycopg.errors.UniqueViolation: duplicate key value violates unique constraint "users_userprofile_user_id_key"
DETAIL: Key (user_id)=(2) already exists.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/inventree/src/backend/InvenTree/manage.py", line 24, in <module>
main()
File "/home/inventree/src/backend/InvenTree/manage.py", line 20, in main
execute_from_command_line(sys.argv)
File "/root/.local/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
utility.execute()
File "/root/.local/lib/python3.11/site-packages/django/core/management/__init__.py", line 436, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/root/.local/lib/python3.11/site-packages/django/core/management/base.py", line 412, in run_from_argv
self.execute(*args, **cmd_options)
File "/root/.local/lib/python3.11/site-packages/django/core/management/base.py", line 458, in execute
output = self.handle(*args, **options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/.local/lib/python3.11/site-packages/django/core/management/commands/loaddata.py", line 102, in handle
self.loaddata(fixture_labels)
File "/root/.local/lib/python3.11/site-packages/django/core/management/commands/loaddata.py", line 163, in loaddata
self.load_label(fixture_label)
File "/root/.local/lib/python3.11/site-packages/django/core/management/commands/loaddata.py", line 253, in load_label
if self.save_obj(obj):
^^^^^^^^^^^^^^^^^^
File "/root/.local/lib/python3.11/site-packages/django/core/management/commands/loaddata.py", line 209, in save_obj
obj.save(using=self.using)
File "/root/.local/lib/python3.11/site-packages/django/core/serializers/base.py", line 288, in save
models.Model.save_base(self.object, using=using, raw=True, **kwargs)
File "/root/.local/lib/python3.11/site-packages/django/db/models/base.py", line 877, in save_base
updated = self._save_table(
^^^^^^^^^^^^^^^^^
File "/root/.local/lib/python3.11/site-packages/django/db/models/base.py", line 990, in _save_table
updated = self._do_update(
^^^^^^^^^^^^^^^^
File "/root/.local/lib/python3.11/site-packages/django/db/models/base.py", line 1054, in _do_update
return filtered._update(values) > 0
^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/.local/lib/python3.11/site-packages/django/db/models/query.py", line 1231, in _update
return query.get_compiler(self.db).execute_sql(CURSOR)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/.local/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 1984, in execute_sql
cursor = super().execute_sql(result_type)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/.local/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 1562, in execute_sql
cursor.execute(sql, params)
File "/root/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 67, in execute
return self._execute_with_wrappers(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
return executor(sql, params, many, context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 84, in _execute
with self.db.wrap_database_errors:
File "/root/.local/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/root/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 89, in _execute
return self.cursor.execute(sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/.local/lib/python3.11/site-packages/psycopg/cursor.py", line 97, in execute
raise ex.with_traceback(None)
django.db.utils.IntegrityError: Problem installing fixture '/home/inventree/data/backup/data-2025-11-05-1443.json.data.json': Could not load users.UserProfile(pk=1): duplicate key value violates unique constraint "users_userprofile_user_id_key"
DETAIL: Key (user_id)=(2) already exists.
ERROR: InvenTree command failed: 'python3 manage.py loaddata '/home/inventree/data/backup/data-2025-11-05-1443.json.data.json' -i --exclude contenttypes --exclude auth.permission --exclude error_report.error --exclude admin.logentry --exclude django_q.schedule --exclude django_q.task --exclude django_q.ormq --exclude exchange.rate --exclude exchange.exchangebackend --exclude common.dataoutput --exclude common.newsfeedentry --exclude common.notificationentry --exclude common.notificationmessage --exclude importer.dataimportsession --exclude importer.dataimportcolumnmap --exclude importer.dataimportrow --exclude auth.group --exclude auth.user'
Importing records should work, as long as the database truly is empty beforehand. Is there any way you can inspect the database to ensure it is actually empty?
@SchrodingersGat I'm getting the same error. I think what is going on is that when django restores the auth users, the signal registered in users/models.py is creating profiles automatically for the restored users, so when these profiles are then restored you get the duplicate key errors. Here is the code snippet in question:
# Signal to create or update user profile when user is saved
@receiver(post_save, sender=User)
def create_or_update_user_profile(sender, instance, created, **kwargs):
"""Create or update user profile when user is saved."""
if created:
UserProfile.objects.create(user=instance)
instance.profile.save()
I stopped the import-records command after restoring the auth-data but before the database records were imported and I can see in my users_userprofile table there are entries corresponding to each added auth_user:
inventree=# select id,metadata,active,type,user_id from users_userprofile;
id | metadata | active | type | user_id
----+----------+--------+----------+---------
1 | {} | t | internal | 1
2 | {} | t | internal | 2
3 | {} | t | internal | 3
4 | {} | t | internal | 4
(4 rows)
Probably the easiest fix would be to disable this signal for loaddata by exiting the signal when the kwarg "raw" is set to true. See more here: https://docs.djangoproject.com/en/6.0/topics/db/fixtures/#how-fixtures-are-saved-to-the-database
If you want I can make a PR with these changes, but it might be more complicated if you rely on these signals working when deserializing into the db in other contexts.
@bbzylstra thanks for tracking this down.
Probably the easiest fix would be to disable this signal for loaddata by exiting the signal when the kwarg "raw" is set to true.
Note that we have other checks for this also:
https://github.com/inventree/InvenTree/blob/57a2de6ffc6f949ab8882b2063bbd8f55a1da48b/src/backend/InvenTree/InvenTree/ready.py#L13
So you might be able to use this also.
In any case, we would welcome a PR to address this!