Skip to content

Commit fe26199

Browse files
authored
Merge pull request #23 from portfoliome/on-conflict-pkey
Reformulate dml upsert
2 parents bef72e5 + b5aa9a1 commit fe26199

File tree

3 files changed

+28
-25
lines changed

3 files changed

+28
-25
lines changed

postpy/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
version_info = (0, 0, 8)
1+
version_info = (0, 0, 9)
22

33
__version__ = '.'.join(map(str, version_info))

postpy/dml.py

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""Data Manipulation Language for Postgresql."""
22

3+
import warnings
4+
35
from foil.iteration import chunks
46
from psycopg2.extras import NamedTupleCursor
57

@@ -83,32 +85,36 @@ def format_upsert_expert(insert_template, column_names, constraint, clause='',
8385

8486
constraint_str = ', '.join(constraint)
8587
non_key_columns = [column for column in column_names if column not in constraint]
86-
non_key_column_str = ', '.join(non_key_columns)
87-
excluded_str = ', '.join('EXCLUDED.' + column for column in non_key_columns)
88+
89+
if non_key_columns:
90+
non_key_column_str = ', '.join(non_key_columns)
91+
excluded_str = ', '.join('EXCLUDED.' + column for column in non_key_columns)
92+
action = (
93+
' DO UPDATE'
94+
' SET ({non_key_columns}) = ({excluded})'
95+
' {clause}').format(non_key_columns=non_key_column_str,
96+
excluded=excluded_str, clause=clause,
97+
table_alias=table_alias)
98+
else:
99+
action = ' DO NOTHING'
88100

89101
statement = (
90102
'{insert_template}'
91103
' ON CONFLICT ({constraint})'
92-
' DO UPDATE'
93-
' SET ({non_key_columns}) = ({excluded})'
94-
' {clause};').format(insert_template=insert_template,
95-
constraint=constraint_str,
96-
non_key_columns=non_key_column_str,
97-
excluded=excluded_str, clause=clause,
98-
table_alias=table_alias)
104+
'{action}').format(insert_template=insert_template,
105+
constraint=constraint_str,
106+
action=action)
107+
99108
return statement
100109

101110

102111
def format_upsert_primary_key(qualified_name, column_names, primary_key_names,
103112
param_style=PYFORMAT):
113+
warning = 'Deprecation Warning. Function will be removed as of version 0.1.0.'
114+
warnings.warn(warning, DeprecationWarning)
104115

105-
if column_names != primary_key_names:
106-
query = format_upsert(qualified_name, column_names, primary_key_names,
107-
param_style=param_style)
108-
else:
109-
# Note: When upsert columns are all primary keys, it's an insert.
110-
query = create_insert_statement(qualified_name, column_names,
111-
param_style=param_style)
116+
query = format_upsert(qualified_name, column_names, primary_key_names,
117+
param_style=param_style)
112118

113119
return query
114120

@@ -148,7 +154,7 @@ def __call__(self, conn, records, chunksize=2500):
148154
class UpsertPrimaryKey:
149155
def __init__(self, qualified_name, column_names, primary_key_names):
150156

151-
self.query = format_upsert_primary_key(
157+
self.query = format_upsert(
152158
qualified_name, column_names, primary_key_names
153159
)
154160

@@ -202,16 +208,12 @@ class CopyFromUpsert(BulkDmlPrimaryKey):
202208
)
203209

204210
def make_dml_query(self):
205-
# Note: When upsert columns are all primary keys, it's an insert.
206211
query = self._INSERT_TEMPLATE.format(
207212
table=self.table.qualified_name, columns=self.column_str,
208213
temp_table=self.copy_table.name
209214
)
210-
211-
if self.table.column_names != self.table.primary_key_columns:
212-
query = format_upsert_expert(query,
213-
self.table.column_names,
214-
self.table.primary_key_columns)
215+
query = format_upsert_expert(query, self.table.column_names,
216+
self.table.primary_key_columns)
215217

216218
return query
217219

tests/test_dml.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,8 @@ def test_when_all_columns_are_primary_keys(self):
194194
self.columns,
195195
self.primary_keys)
196196

197-
expected = 'INSERT INTO foobar (foo, bar) VALUES (%s, %s)'
197+
expected = ('INSERT INTO foobar AS current (foo, bar) VALUES (%s, %s)'
198+
' ON CONFLICT (foo, bar) DO NOTHING')
198199
result = upserter.query
199200

200201
self.assertSQLStatementEqual(expected, result)

0 commit comments

Comments
 (0)