summaryrefslogtreecommitdiff
path: root/django/db/models/sql
diff options
context:
space:
mode:
authorTom <tom@tomforb.es>2017-10-03 00:35:38 +0100
committerTim Graham <timograham@gmail.com>2018-08-03 17:40:46 -0400
commitf1fbef6cd171ddfae41fcc901f1f60ccad039f51 (patch)
tree414e5d00478371dd01e0bf69467cc32301260cb5 /django/db/models/sql
parent45086c294d63ac8787cebff2accd1680ac844138 (diff)
Fixed #28668 -- Allowed QuerySet.bulk_create() to ignore insert conflicts.
Diffstat (limited to 'django/db/models/sql')
-rw-r--r--django/db/models/sql/compiler.py12
-rw-r--r--django/db/models/sql/subqueries.py3
2 files changed, 13 insertions, 2 deletions
diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py
index 66ff004b6e..fd6337a18a 100644
--- a/django/db/models/sql/compiler.py
+++ b/django/db/models/sql/compiler.py
@@ -1232,7 +1232,8 @@ class SQLInsertCompiler(SQLCompiler):
# going to be column names (so we can avoid the extra overhead).
qn = self.connection.ops.quote_name
opts = self.query.get_meta()
- result = ['INSERT INTO %s' % qn(opts.db_table)]
+ insert_statement = self.connection.ops.insert_statement(ignore_conflicts=self.query.ignore_conflicts)
+ result = ['%s %s' % (insert_statement, qn(opts.db_table))]
fields = self.query.fields or [opts.pk]
result.append('(%s)' % ', '.join(qn(f.column) for f in fields))
@@ -1254,6 +1255,9 @@ class SQLInsertCompiler(SQLCompiler):
placeholder_rows, param_rows = self.assemble_as_sql(fields, value_rows)
+ ignore_conflicts_suffix_sql = self.connection.ops.ignore_conflicts_suffix_sql(
+ ignore_conflicts=self.query.ignore_conflicts
+ )
if self.return_id and self.connection.features.can_return_id_from_insert:
if self.connection.features.can_return_ids_from_bulk_insert:
result.append(self.connection.ops.bulk_insert_sql(fields, placeholder_rows))
@@ -1261,6 +1265,8 @@ class SQLInsertCompiler(SQLCompiler):
else:
result.append("VALUES (%s)" % ", ".join(placeholder_rows[0]))
params = [param_rows[0]]
+ if ignore_conflicts_suffix_sql:
+ result.append(ignore_conflicts_suffix_sql)
col = "%s.%s" % (qn(opts.db_table), qn(opts.pk.column))
r_fmt, r_params = self.connection.ops.return_insert_id()
# Skip empty r_fmt to allow subclasses to customize behavior for
@@ -1272,8 +1278,12 @@ class SQLInsertCompiler(SQLCompiler):
if can_bulk:
result.append(self.connection.ops.bulk_insert_sql(fields, placeholder_rows))
+ if ignore_conflicts_suffix_sql:
+ result.append(ignore_conflicts_suffix_sql)
return [(" ".join(result), tuple(p for ps in param_rows for p in ps))]
else:
+ if ignore_conflicts_suffix_sql:
+ result.append(ignore_conflicts_suffix_sql)
return [
(" ".join(result + ["VALUES (%s)" % ", ".join(p)]), vals)
for p, vals in zip(placeholder_rows, param_rows)
diff --git a/django/db/models/sql/subqueries.py b/django/db/models/sql/subqueries.py
index e877daa4e6..fbc265d113 100644
--- a/django/db/models/sql/subqueries.py
+++ b/django/db/models/sql/subqueries.py
@@ -169,10 +169,11 @@ class UpdateQuery(Query):
class InsertQuery(Query):
compiler = 'SQLInsertCompiler'
- def __init__(self, *args, **kwargs):
+ def __init__(self, *args, ignore_conflicts=False, **kwargs):
super().__init__(*args, **kwargs)
self.fields = []
self.objs = []
+ self.ignore_conflicts = ignore_conflicts
def insert_values(self, fields, objs, raw=False):
self.fields = fields