add helper function for execute_values

Make psycopg2's convenience function accessible through
the cursor.
This commit is contained in:
Sarah Hoffmann
2021-07-12 21:08:20 +02:00
parent 06602b4ec0
commit 6f6681ce67
5 changed files with 32 additions and 27 deletions

View File

@@ -26,6 +26,16 @@ class _Cursor(psycopg2.extras.DictCursor):
super().execute(query, args) super().execute(query, args)
def execute_values(self, sql, argslist, template=None):
""" Wrapper for the psycopg2 convenience function to execute
SQL for a list of values.
"""
LOG.debug("SQL execute_values(%s, %s)", sql, argslist)
psycopg2.extras.execute_values(self, sql, argslist, template=template)
def scalar(self, sql, args=None): def scalar(self, sql, args=None):
""" Execute query that returns a single value. The value is returned. """ Execute query that returns a single value. The value is returned.
If the query yields more than one row, a ValueError is raised. If the query yields more than one row, a ValueError is raised.

View File

@@ -9,8 +9,6 @@ import re
from textwrap import dedent from textwrap import dedent
from pathlib import Path from pathlib import Path
import psycopg2.extras
from nominatim.db.connection import connect from nominatim.db.connection import connect
from nominatim.db.properties import set_property, get_property from nominatim.db.properties import set_property, get_property
from nominatim.db.utils import CopyBuffer from nominatim.db.utils import CopyBuffer
@@ -359,8 +357,7 @@ class LegacyICUNameAnalyzer:
to_delete = existing_phrases - new_phrases to_delete = existing_phrases - new_phrases
if to_delete: if to_delete:
psycopg2.extras.execute_values( cursor.execute_values(
cursor,
""" DELETE FROM word USING (VALUES %s) as v(name, in_class, in_type, op) """ DELETE FROM word USING (VALUES %s) as v(name, in_class, in_type, op)
WHERE word = name and class = in_class and type = in_type WHERE word = name and class = in_class and type = in_type
and ((op = '-' and operator is null) or op = operator)""", and ((op = '-' and operator is null) or op = operator)""",

View File

@@ -370,8 +370,7 @@ class LegacyNameAnalyzer:
to_delete = existing_phrases - norm_phrases to_delete = existing_phrases - norm_phrases
if to_add: if to_add:
psycopg2.extras.execute_values( cur.execute_values(
cur,
""" INSERT INTO word (word_id, word_token, word, class, type, """ INSERT INTO word (word_id, word_token, word, class, type,
search_name_count, operator) search_name_count, operator)
(SELECT nextval('seq_word'), ' ' || make_standard_name(name), name, (SELECT nextval('seq_word'), ' ' || make_standard_name(name), name,
@@ -381,8 +380,7 @@ class LegacyNameAnalyzer:
to_add) to_add)
if to_delete and should_replace: if to_delete and should_replace:
psycopg2.extras.execute_values( cur.execute_values(
cur,
""" DELETE FROM word USING (VALUES %s) as v(name, in_class, in_type, op) """ DELETE FROM word USING (VALUES %s) as v(name, in_class, in_type, op)
WHERE word = name and class = in_class and type = in_type WHERE word = name and class = in_class and type = in_type
and ((op = '-' and operator is null) or op = operator)""", and ((op = '-' and operator is null) or op = operator)""",

View File

@@ -7,7 +7,7 @@ import gzip
import logging import logging
from math import isfinite from math import isfinite
from psycopg2.extras import execute_values from psycopg2 import sql as pysql
from nominatim.db.connection import connect from nominatim.db.connection import connect
@@ -52,27 +52,26 @@ class _CountryPostcodesCollector:
with conn.cursor() as cur: with conn.cursor() as cur:
if to_add: if to_add:
execute_values(cur, cur.execute_values(
"""INSERT INTO location_postcode """INSERT INTO location_postcode
(place_id, indexed_status, country_code, (place_id, indexed_status, country_code,
postcode, geometry) VALUES %s""", postcode, geometry) VALUES %s""",
to_add, to_add,
template="""(nextval('seq_place'), 1, '{}', template=pysql.SQL("""(nextval('seq_place'), 1, {},
%s, 'SRID=4326;POINT(%s %s)') %s, 'SRID=4326;POINT(%s %s)')
""".format(self.country)) """).format(pysql.Literal(self.country)))
if to_delete: if to_delete:
cur.execute("""DELETE FROM location_postcode cur.execute("""DELETE FROM location_postcode
WHERE country_code = %s and postcode = any(%s) WHERE country_code = %s and postcode = any(%s)
""", (self.country, to_delete)) """, (self.country, to_delete))
if to_update: if to_update:
execute_values(cur, cur.execute_values(
"""UPDATE location_postcode pysql.SQL("""UPDATE location_postcode
SET indexed_status = 2, SET indexed_status = 2,
geometry = ST_SetSRID(ST_Point(v.x, v.y), 4326) geometry = ST_SetSRID(ST_Point(v.x, v.y), 4326)
FROM (VALUES %s) AS v (pc, x, y) FROM (VALUES %s) AS v (pc, x, y)
WHERE country_code = '{}' and postcode = pc WHERE country_code = {} and postcode = pc
""".format(self.country), """).format(pysql.Literal(self.country)), to_update)
to_update)
def _compute_changes(self, conn): def _compute_changes(self, conn):

View File

@@ -5,7 +5,7 @@ import json
import logging import logging
from textwrap import dedent from textwrap import dedent
from psycopg2.extras import execute_values from psycopg2 import sql as pysql
from nominatim.db.utils import execute_file from nominatim.db.utils import execute_file
from nominatim.db.sql_preprocessor import SQLPreprocessor from nominatim.db.sql_preprocessor import SQLPreprocessor
@@ -57,7 +57,8 @@ def load_address_levels(conn, table, levels):
rank_search SMALLINT, rank_search SMALLINT,
rank_address SMALLINT)""".format(table)) rank_address SMALLINT)""".format(table))
execute_values(cur, "INSERT INTO {} VALUES %s".format(table), rows) cur.execute_values(pysql.SQL("INSERT INTO {} VALUES %s")
.format(pysql.Identifier(table)), rows)
cur.execute('CREATE UNIQUE INDEX ON {} (country_code, class, type)'.format(table)) cur.execute('CREATE UNIQUE INDEX ON {} (country_code, class, type)'.format(table))