Repository: doccano/doccano

Issue:
[Enhancement request] Avoid duplicate key value error on launching
Enhancement description
---------
I have these errors in log on each start:
```
postgres_1  | 2020-03-04 05:34:30.467 UTC [27] ERROR:  duplicate key value violates unique constraint "api_role_name_key"
postgres_1  | 2020-03-04 05:34:30.467 UTC [27] DETAIL:  Key (name)=(project_admin) already exists.
postgres_1  | 2020-03-04 05:34:30.467 UTC [27] STATEMENT:  INSERT INTO "api_role" ("name", "description", "created_at", "updated_at") VALUES ('project_admin', '', '2020-03-04T05:34:30.460290+00:00'::timestamptz, '2020-03-04T05:34:30.460312+00:00'::timestamptz) RETURNING "api_role"."id"
backend_1   | Datbase Error: "duplicate key value violates unique constraint "api_role_name_key"
backend_1   | DETAIL:  Key (name)=(project_admin) already exists.
backend_1   | "
postgres_1  | 2020-03-04 05:34:30.468 UTC [27] ERROR:  duplicate key value violates unique constraint "api_role_name_key"
postgres_1  | 2020-03-04 05:34:30.468 UTC [27] DETAIL:  Key (name)=(annotator) already exists.
postgres_1  | 2020-03-04 05:34:30.468 UTC [27] STATEMENT:  INSERT INTO "api_role" ("name", "description", "created_at", "updated_at") VALUES ('annotator', '', '2020-03-04T05:34:30.467909+00:00'::timestamptz, '2020-03-04T05:34:30.467926+00:00'::timestamptz) RETURNING "api_role"."id"
backend_1   | Datbase Error: "duplicate key value violates unique constraint "api_role_name_key"
backend_1   | DETAIL:  Key (name)=(annotator) already exists.
backend_1   | "
postgres_1  | 2020-03-04 05:34:30.468 UTC [27] ERROR:  duplicate key value violates unique constraint "api_role_name_key"
postgres_1  | 2020-03-04 05:34:30.468 UTC [27] DETAIL:  Key (name)=(annotation_approver) already exists.
postgres_1  | 2020-03-04 05:34:30.468 UTC [27] STATEMENT:  INSERT INTO "api_role" ("name", "description", "created_at", "updated_at") VALUES ('annotation_approver', '', '2020-03-04T05:34:30.468689+00:00'::timestamptz, '2020-03-04T05:34:30.468706+00:00'::timestamptz) RETURNING "api_role"."id"
backend_1   | Datbase Error: "duplicate key value violates unique constraint "api_role_name_key"
backend_1   | DETAIL:  Key (name)=(annotation_approver) already exists.
backend_1   | "
postgres_1  | 2020-03-04 05:34:32.026 UTC [28] ERROR:  duplicate key value violates unique constraint "auth_user_username_key"
postgres_1  | 2020-03-04 05:34:32.026 UTC [28] DETAIL:  Key (username)=(admin) already exists.
postgres_1  | 2020-03-04 05:34:32.026 UTC [28] STATEMENT:  INSERT INTO "auth_user" ("password", "last_login", "is_superuser", "username", "first_name", "last_name", "email", "is_staff", "is_active", "date_joined") VALUES ('<...>', NULL, true, 'admin', '', '', 'admin@example.com', true, true, '2020-03-04T05:34:32.023520+00:00'::timestamptz) RETURNING "auth_user"."id"
backend_1   | User admin already exists.
backend_1   | CommandError: Error: That username is already taken.
```

Propose to check existence of specified table's rows before creation to avoid these errors.


Discussion:
Thank you for reporting the issue. Please provide the procedure to reproduce at first.
@icoxfog417 , just `$ /opt/docker-compose -f docker-compose.prod.yml up` twice. You'll see it the second time. Oh, yes: turn on `debug` first.
@icoxfog417 , about changing the title: not only that, see last lines.
```
postgres_1  | 2020-03-04 05:34:32.026 UTC [28] ERROR:  duplicate key value violates unique constraint "auth_user_username_key"
postgres_1  | 2020-03-04 05:34:32.026 UTC [28] DETAIL:  Key (username)=(admin) already exists.
postgres_1  | 2020-03-04 05:34:32.026 UTC [28] STATEMENT:  INSERT INTO "auth_user" ("password", "last_login", "is_superuser", "username", "first_name", "last_name", "email", "is_staff", "is_active", "date_joined") VALUES ('<...>', NULL, true, 'admin', '', '', 'admin@example.com', true, true, '2020-03-04T05:34:32.023520+00:00'::timestamptz) RETURNING "auth_user"."id"
backend_1   | User admin already exists.
```

Resolving patch:
diff --git a/app/server/management/commands/create_roles.py b/app/server/management/commands/create_roles.py
--- a/app/server/management/commands/create_roles.py
+++ b/app/server/management/commands/create_roles.py
@@ -13,11 +13,13 @@ def handle(self, *args, **options):
         except KeyError as key_error:
             self.stderr.write(self.style.ERROR(f'Missing Key: "{key_error}"'))
         for role_name in role_names:
+            if Role.objects.filter(name=role_name).exists():
+                continue
             role = Role()
             role.name = role_name
             try:
                 role.save()
             except DatabaseError as db_error:
-                self.stderr.write(self.style.ERROR(f'Datbase Error: "{db_error}"'))
+                self.stderr.write(self.style.ERROR(f'Database Error: "{db_error}"'))
             else:
                 self.stdout.write(self.style.SUCCESS(f'Role created successfully "{role_name}"'))


Test patch: