getsentry / getsentry/self-hosted
Migration error on table `sentry_organizationcontributors` during upgrading to 26.7.1
- Dominant language
- Shell
- Stars
- 9.6k
- Forks
- 2k
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 15
Description
You will face two kinds of error:
```
django.db.utils.IntegrityError: check constraint "sentry_organizationcontributors_hostname_6f7999b1_notnull" of relation "sentry_organizationcontributors" is violated by some row
SQL: ALTER TABLE "sentry_organizationcontributors" VALIDATE CONSTRAINT "sentry_organizationcontributors_hostname_6f7999b1_notnull"
```
From the source code, they [described OrganizationContributors](https://github.com/getsentry/sentry/blob/ae93d339a993d4bf41add7ff86567d328bb58e5f/src/sentry/models/organizationcontributors.py#L38-L43) as:
```
Tracks external contributors and their activity for an organization.
This model stores information about contributors associated with an
integration for a specific organization, including their external identity
and how many actions they have taken.
```
The only `INSERT` query is here: https://github.com/getsentry/sentry/blob/ae93d339a993d4bf41add7ff86567d328bb58e5f/src/sentry/seer/code_review/contributor_seats.py#L150-L158
```python
def get_or_create_contributor(
*,
organization: Organization,
integration: Integration | RpcIntegration,
external_identifier: str,
alias: str | None,
) -> OrganizationContributors | None:
"""
TODO(CW-1539): Replace with get_or_create() after the contributor deduplication
migration has completed.
"""
try:
hostname = instance_hostname(integration)
except InstanceHostnameError as e:
sentry_sdk.capture_exception(e)
return None
if contributor := get_canonical_contributor(
organization_id=organization.id,
integration=integration,
external_identifier=external_identifier,
):
return contributor
try:
with transaction.atomic(router.db_for_write(OrganizationContributors)):
return OrganizationContributors.objects.create(
organization_id=organization.id,
integration_id=integration.id,
external_identifier=external_identifier,
provider=integration.provider,
hostname=hostname,
alias=alias,
)
except IntegrityError:
contributor = get_canonical_contributor(
organization_id=organization.id,
integration=integration,
external_identifier=external_identifier,
)
if not contributor:
raise
return contributor
```
For my own case (the second one), the `hostname` fields are empty (null), therefore I need to update each fields to the source code management tool that I use (in this case, GitHub, therefore the value should be "github.com"). Refer to this code: https://github.com/getsentry/sentry/blob/ae93d339a993d4bf41add7ff86567d328bb58e5f/src/sentry/integrations/utils/hostname.py#L10-L32
Therefore the solution for this is changing the value directly on Postgres:
```bash
$ docker compose exec postgres psql -U postgres -d postgres
postgres=# SELECT * FROM sentry_organizationcontributors;
postgres=# UPDATE sentry_organizationcontributors SET hostname = 'github.com';
```
Then re-run `./install.sh`.
---
When you execute it again, you might come across this error:
> I get the following error when upgrading from 26.7.0
>
> ```log
> File "/.venv/lib/python3.13/site-packages/django/db/utils.py", line 91, in __exit__
> raise dj_exc_value.with_traceback(traceback) from exc_value
> File "/.venv/lib/python3.13/site-packages/django/db/backends/utils.py", line 103, in _execute
> return self.cursor.execute(sql)
> ~~~~~~~~~~~~~~~~~~~^^^^^
> File "/usr/src/sentry/src/sentry/db/postgres/decorators.py", line 16, in inner
> return func(self, *args, **kwargs)
> File "/usr/src/sentry/src/sentry/db/postgres/base.py", line 96, in execute
> return self.cursor.execute(sql)
> ~~~~~~~~~~~~~~~~~~~^^^^^
> django.db.utils.ProgrammingError: constraint "sentry_organizationcontributors_hostname_6f7999b1_notnull" for relation "sentry_organizationcontributors" already exists
>
> SQL: ALTER TABLE "sentry_organizationcontributors" ADD CONSTRAINT "sentry_organizationcontributors_hostname_6f7999b1_notnull" CHECK ("hostname" IS NOT NULL) NOT VALID
>
> Error in install/set-up-and-migrate-database.sh:23.
> '$dcr web upgrade --create-kafka-topics' exited with status 1
> -> ./install.sh:main:45
> --> install/set-up-and-migrate-database.sh:source:23
> ```
_Originally posted by @MagnusHBrunbjerg in [#4426](https://github.com/getsentry/self-hosted/issues/4426#issuecomment-5078883739)_
The solution for this is to simply drop the constraint. Execute `\d ` first to ensure the constraint is there. Then just drop it.
```bash
$ docker compose exec postgres psql -U postgres -d postgres
postgres=# \d sentry_organizationcontributors
Table "public.sentry_organizationcontributors"
Column | Type | Collation | Nullable | Default
---------------------+--------------------------+-----------+----------+----------------------------------
id | bigint | | not null | generated by default as identity
integration_id | bigint | | not null |
external_identifier | character varying(255) | | not null |
alias | character varying(255) | | |
num_actions | integer | | not null |
date_added | timestamp with time zone | | not null |
date_updated | timestamp with time zone | | not null |
organization_id | bigint | | not null |
provider | character varying(64) | | |
hostname | character varying(255) | | |
Indexes:
"sentry_organizationcontributors_pkey" PRIMARY KEY, btree (id)
"sentry_oc_org_date_upd_idx" btree (organization_id, date_updated)
"sentry_organizationcontr_external_identifier_ef77d39a_like" btree (external_identifier varchar_pattern_ops)
"sentry_organizationcontributors_external_identifier_ef77d39a" btree (external_identifier)
"sentry_organizationcontributors_integration_id_d13b5795" btree (integration_id)
"sentry_organizationcontributors_organization_id_93cc3a35" btree (organization_id)
"sentry_orgcont_unique_org_cont" UNIQUE CONSTRAINT, btree (organization_id, integration_id, external_identifier)
Check constraints:
"sentry_organizationcontributors_hostname_6f7999b1_notnull" CHECK (hostname IS NOT NULL) NOT VALID
Foreign-key constraints:
"sentry_organizationc_organization_id_93cc3a35_fk_sentry_or" FOREIGN KEY (organization_id) REFERENCES sentry_organization(id) DEFERRABLE INITIALLY DEFERRED
Referenced by:
TABLE "sentry_organizationcontributoraction" CONSTRAINT "sentry_organizationc_organization_contrib_db78e1a3_fk_sentry_or" FOREIGN KEY (organization_contributor_id) REFERENCES sentry_organizationcontributors(id) DEFERRABLE INITIALLY DEFERRED
postgres=# ALTER TABLE sentry_organizationcontributors DROP CONSTRAINT sentry_organizationcontributors_hostname_6f7999b1_notnull;
```
Then re-run `./install.sh`.
---
Oh no, it's still happening!!!
Just truncate it and drop the constraint again.
```bash
$ docker compose exec postgres psql -U postgres -d postgres
postgres=# TRUNCATE TABLE sentry_organizationcontributors CASCADE;
postgres=# ALTER TABLE sentry_organizationcontributors DROP CONSTRAINT sentry_organizationcontributors_provider_4cfc5f3a_notnull;
```
Contributor guide
Research direction
Reproduce the 26.7.0-to-26.7.1 upgrade and start with the migration error for sentry_organizationcontributors. Read src/sentry/models/organizationcontributors.py, src/sentry/seer/code_review/contributor_seats.py, and src/sentry/integrations/utils/hostname.py to trace how hostname values are created. Done means the upgrade completes without invalid or duplicate constraints and without requiring destructive manual database changes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- django, docker-compose, postgresql, python
- Domain
- databases, devops
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100