artofhuman/django-pg-upsert
artofhuman/django-pg-upsert has 31 GitHub stars and 6 forks. GitHot measured 0 stars in 24 hours, 0 in 7 days, and 0 in 15 days. Last checked 2026-11-12 23:23 UTC. Last push 2026-08-12.
Support Postgres native upsert (INSERT ... ON CONFLICT) for django
实测星标增长
- 24小时
- 0
- 7天
- 0
- 15天
- 0
- 1个月
- 正在收集历史
各周期内的星标净变化,周期相互重叠,并非每日新增。缺失的测量保持空白。星标代表关注度,不代表软件质量。
README.md
原文django-pg-upsert
This package adds support for the native Postgres upsert (INSERT ... ON CONFLICT) to Django.
Installation
pip install django-pg-upsert
Usage
As a manager
from django.db import models
from django_pg_upsert import PgUpsertManager
class Pet(models.Model):
name = models.CharField(max_length=30, unique=True)
age = models.PositiveIntegerField()
objects = PgUpsertManager()
Pet.objects.insert_conflict(data={"name": "dog", "age": 12})
# The second query does not insert a record and does not raise an error.
Pet.objects.insert_conflict(data={"name": "dog", "age": 20})
This code produces the SQL statement:
[
'INSERT INTO "pets" ("name", "age") VALUES (%s, %s) ON CONFLICT DO NOTHING',
("dog", 12),
]
Explicit constraint name
Pet.objects.insert_conflict(
data={"name": "dog", "age": 12},
constraint="pet_name_uniq"
)
[
'INSERT INTO "pets" ("name", "age") VALUES (%s, %s) ON CONFLICT ON CONSTRAINT pet_name_uniq DO NOTHING',
("dog", 12),
]
Using field names
Pet.objects.insert_conflict(
data={"name": "dog", "age": 12},
fields=["name"]
)
[
'INSERT INTO "pets" ("name", "age") VALUES (%s, %s) ON CONFLICT ("name") DO NOTHING',
("dog", 12),
]
As a standalone function
import django_pg_upsert
pet = Pet(name="dog", age=12)
django_pg_upsert.insert_conflict(pet)
django_pg_upsert.insert_conflict(pet, constraint="pet_name_uniq")
django_pg_upsert.insert_conflict(pet, fields=["name"])
Update
Pet.objects.insert_conflict(
data={"name": "dog", "age": 100},
fields=["name"],
update=["age"]
)
or
django_pg_upsert.insert_conflict(pet, fields=["name"], update=["age"])
[
'INSERT INTO "pets" ("name", "age") VALUES (%s, %s) ON CONFLICT ("name") DO UPDATE SET age = EXCLUDED.age',
("dog", 100),
]
Update with condition
The update_where argument restricts which existing rows are updated
(ON CONFLICT ... DO UPDATE SET ... WHERE ...). It accepts a Q object.
from django.db.models import Q
Pet.objects.insert_conflict(
data={"name": "dog", "age": 100},
fields=["name"],
update=["age"],
update_where=Q(age__lt=100),
)
[
'INSERT INTO "pets" ("name", "age") VALUES (%s, %s) ON CONFLICT ("name") DO UPDATE SET age = EXCLUDED.age WHERE "pets"."age" < %s',
("dog", 100, 100),
]
The argument also accepts a raw SQL string. Use a raw string to reference the
proposed row through EXCLUDED.
django_pg_upsert.insert_conflict(
pet,
fields=["name"],
update=["age"],
update_where="EXCLUDED.age > pets.age",
)
[
'INSERT INTO "pets" ("name", "age") VALUES (%s, %s) ON CONFLICT ("name") DO UPDATE SET age = EXCLUDED.age WHERE EXCLUDED.age > pets.age',
("dog", 100),
]
Do not build a raw string from user input. The package inlines the string into the statement as is.
Batch
To insert many rows in one statement, pass a list. The manager accepts a list of dictionaries. The standalone function accepts a list of model objects. All other arguments work as they do for a single row.
Pet.objects.insert_conflict(
data=[
{"name": "dog", "age": 12},
{"name": "cat", "age": 8},
],
fields=["name"],
update=["age"],
)
or
dog = Pet(name="dog", age=12)
cat = Pet(name="cat", age=8)
django_pg_upsert.insert_conflict([dog, cat], fields=["name"], update=["age"])
Both calls produce one statement with one row set for each object:
[
'INSERT INTO "pets" ("name", "age") VALUES (%s, %s), (%s, %s) ON CONFLICT ("name") DO UPDATE SET age = EXCLUDED.age',
("dog", 12, "cat", 8),
]
Motivation
django-postgres-extra also has a pg upsert method, but that package requires a different DB backend in the Django settings. Sometimes this change is not possible.
django-pg-upsert solves only one problem and depends only on Django. It is not a Swiss army knife.
探索相关项目
Asabeneh/30-Days-Of-Python
30 Days of Python 编程挑战是一份循序渐进的指南,用于在 30 天内学习 Python 编程语言。这项挑战可能需要超过 100 天。请按自己的节奏进行。这些视频或许也有帮助:https://www.youtube.com/channel/UC7PNRuno1rzYPb1xLa4yktw
78,618 星标grafana/grafana
开放且可组合的可观测性与数据可视化平台。可对来自 Prometheus、Loki、Elasticsearch、InfluxDB、Postgres 等众多数据源的指标、日志和追踪进行可视化。
77,859 星标redis/redis
对于正在构建实时数据驱动应用的开发者而言,Redis 是首选、速度最快且功能最丰富的缓存、数据结构服务器和文档与向量查询引擎。
77,472 星标apache/superset
Apache Superset 是一个数据可视化与数据探索平台
75,495 星标