Skip to content

Commit 38fcc2b

Browse files
committed
Fix support for upserting models with foreign key relationships
1 parent 0814153 commit 38fcc2b

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

psqlextra/manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def _get_upsert_fields(self, kwargs):
160160
update_fields = []
161161

162162
for field in model_instance._meta.local_concrete_fields:
163-
if field.name in kwargs:
163+
if field.name in kwargs or field.column in kwargs:
164164
insert_fields.append(field)
165165
update_fields.append(field)
166166
continue

tests/test_upsert.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ class UpsertTest(TestCase):
1212
"""Tests whether the :see:upsert functionality works correctly."""
1313

1414
def test_simple(self):
15+
"""Tests whether simple upserts work correctly."""
16+
1517
model = get_fake_model({
1618
'title': HStoreField(uniqueness=['key1']),
1719
'cookies': models.CharField(max_length=255, null=True)
1820
})
1921

20-
obj = model.objects.upsert(
22+
obj = model.objects.upsert_and_get(
2123
title={'key1': 'beer'},
2224
cookies='cheers'
2325
)
@@ -26,10 +28,15 @@ def test_simple(self):
2628
title={'key1': 'beer'}
2729
)
2830

31+
obj1.refresh_from_db()
32+
2933
assert obj1.title['key1'] == 'beer'
30-
assert obj1.cookies == 'cheers'
34+
assert obj1.cookies == obj.cookies
3135

3236
def test_auto_fields(self):
37+
"""Asserts that fields that automatically add something
38+
to the model automatically still work properly when upserting."""
39+
3340
model = get_fake_model({
3441
'title': models.CharField(max_length=255, unique=True),
3542
'date_added': models.DateTimeField(auto_now_add=True),
@@ -52,3 +59,32 @@ def test_auto_fields(self):
5259

5360
assert obj1.date_added == obj2.date_added
5461
assert obj1.date_updated != obj2.date_updated
62+
63+
def test_foreign_key(self):
64+
"""Asserts that models with foreign key relationships
65+
can safely be upserted."""
66+
67+
model1 = get_fake_model({
68+
'name': models.CharField(max_length=255, unique=True)
69+
})
70+
71+
model2 = get_fake_model({
72+
'name': models.CharField(max_length=255, unique=True),
73+
'model1': models.ForeignKey(model1)
74+
})
75+
76+
model1_row = model1.objects.upsert_and_get(name='item1')
77+
78+
# upsert by id, that should work
79+
model2.objects.upsert(name='item1', model1_id=model1_row.id)
80+
81+
model2_row = model2.objects.get(name='item1')
82+
assert model2_row.name == 'item1'
83+
assert model2_row.model1.id == model1_row.id
84+
85+
# upsert by object, that should also work
86+
model2.objects.upsert(name='item2', model1=model1_row)
87+
88+
model2_row = model2.objects.get(name='item2')
89+
assert model2_row.name == 'item2'
90+
assert model2_row.model1.id == model1_row.id

0 commit comments

Comments
 (0)