|
| 1 | +import pytest |
| 2 | +from django.core.exceptions import SuspiciousOperation |
| 3 | +from django.db import connection, models |
1 | 4 | from django.test import TestCase
|
2 | 5 |
|
3 | 6 | from psqlextra import HStoreField
|
4 | 7 |
|
5 | 8 | from .fake_model import get_fake_model
|
6 |
| -from django.db import models |
7 |
| -import pytest |
8 | 9 |
|
9 |
| -from django.core.exceptions import SuspiciousOperation |
10 | 10 |
|
11 | 11 | @pytest.mark.django_db
|
12 | 12 | class UpsertTest(TestCase):
|
@@ -172,3 +172,33 @@ def test_invalid_conflict_target(self):
|
172 | 172 | title='beer'
|
173 | 173 | )
|
174 | 174 | )
|
| 175 | + |
| 176 | + def test_outdated_model(self): |
| 177 | + """Tests whether upsert_and_get properly handles |
| 178 | + fields that are in the database but not on the model. |
| 179 | +
|
| 180 | + This happens if somebody manually modified the database |
| 181 | + to add a column that is not present in the model. |
| 182 | +
|
| 183 | + This should be handled properly by ignoring the column |
| 184 | + returned by the database. |
| 185 | + """ |
| 186 | + |
| 187 | + model = get_fake_model({ |
| 188 | + 'title': models.CharField(max_length=140, unique=True) |
| 189 | + }) |
| 190 | + |
| 191 | + # manually create the colum that is not on the model |
| 192 | + with connection.cursor() as cursor: |
| 193 | + cursor.execute(( |
| 194 | + 'ALTER TABLE {table} ' |
| 195 | + 'ADD COLUMN beer character varying(50);' |
| 196 | + ).format(table=model._meta.db_table)) |
| 197 | + |
| 198 | + # without proper handling, this would fail with a TypeError |
| 199 | + model.objects.upsert_and_get( |
| 200 | + conflict_target=['title'], |
| 201 | + fields=dict( |
| 202 | + title='beer' |
| 203 | + ) |
| 204 | + ) |
0 commit comments