@@ -34,9 +34,11 @@ missing_modules = []
3434
3535try :
3636 import psycopg2 as psycopg
37+ from psycopg2 import sql
3738except ImportError :
3839 try :
3940 import psycopg
41+ from psycopg import sql
4042 except ImportError :
4143 missing_modules .append ('psycopg2' )
4244
@@ -49,6 +51,10 @@ except ImportError:
4951
5052LOG = logging .getLogger ()
5153
54+ # Will be replaced when installed via CMake.
55+ INSTALL_PREFIX = '@OSM2PGSQL_BINDIR@/'
56+ if INSTALL_PREFIX .startswith ('@' ):
57+ INSTALL_PREFIX = ''
5258
5359def pretty_format_timedelta (seconds ):
5460 minutes = int (seconds / 60 )
@@ -76,21 +82,28 @@ def connect(args):
7682 """ Create a connection from the given command line arguments.
7783 """
7884 # If dbname looks like a conninfo string use it as such
79- if any (part in args .database for part in ['=' , '://' ]):
85+ if args . database and any (part in args .database for part in ['=' , '://' ]):
8086 return psycopg .connect (args .database )
8187
8288 return psycopg .connect (dbname = args .database , user = args .username ,
8389 host = args .host , port = args .port )
8490
8591
92+ def table_exists (conn , table_name ):
93+ with conn .cursor () as cur :
94+ cur .execute ('SELECT * FROM pg_tables where tablename = %s' , (table_name , ))
95+ return cur .rowcount > 0
96+
97+
8698def compute_database_date (conn , prefix ):
8799 """ Determine the date of the database from the newest object in the
88100 database.
89101 """
90102 # First, find the way with the highest ID in the database
91103 # Using nodes would be more reliable but those are not cached by osm2pgsql.
92104 with conn .cursor () as cur :
93- cur .execute ("SELECT max(id) FROM {}_ways" .format (prefix ))
105+ table = sql .Identifier (f'{ prefix } _ways' )
106+ cur .execute (sql .SQL ("SELECT max(id) FROM {}" ).format (table ))
94107 osmid = cur .fetchone ()[0 ] if cur .rowcount == 1 else None
95108
96109 if osmid is None :
@@ -127,13 +140,13 @@ def setup_replication_state(conn, table, base_url, seq, date):
127140 the given state.
128141 """
129142 with conn .cursor () as cur :
130- cur .execute ('DROP TABLE IF EXISTS "{}"' .format (table ))
131- cur .execute ("""CREATE TABLE "{}"
132- (url TEXT,
133- sequence INTEGER,
134- importdate TIMESTAMP WITH TIME ZONE)
135- """ .format (table ))
136- cur .execute ('INSERT INTO "{}" VALUES(%s, %s, %s)' .format (table ),
143+ cur .execute (sql . SQL ( 'DROP TABLE IF EXISTS {}' ) .format (table ))
144+ cur .execute (sql . SQL ( """CREATE TABLE {}
145+ (url TEXT,
146+ sequence INTEGER,
147+ importdate TIMESTAMP WITH TIME ZONE)
148+ """ ) .format (table ))
149+ cur .execute (sql . SQL ( 'INSERT INTO {} VALUES(%s, %s, %s)' ) .format (table ),
137150 (base_url , seq , date ))
138151 conn .commit ()
139152
@@ -144,10 +157,10 @@ def update_replication_state(conn, table, seq, date):
144157 """
145158 with conn .cursor () as cur :
146159 if date is not None :
147- cur .execute ('UPDATE "{}" SET sequence=%s, importdate=%s' .format (table ),
160+ cur .execute (sql . SQL ( 'UPDATE {} SET sequence=%s, importdate=%s' ) .format (table ),
148161 (seq , date ))
149162 else :
150- cur .execute ('UPDATE "{}" SET sequence=%s' .format (table ),
163+ cur .execute (sql . SQL ( 'UPDATE {} SET sequence=%s' ) .format (table ),
151164 (seq ,))
152165
153166 conn .commit ()
@@ -196,13 +209,12 @@ def status(conn, args):
196209
197210 results = {}
198211
199- with conn .cursor () as cur :
200- cur .execute ('SELECT * FROM pg_tables where tablename = %s' , (args .table , ))
201- if cur .rowcount < 1 :
202- results ['status' ] = 1
203- results ['error' ] = "Cannot find replication status table. Run 'osm2pgsql-replication init' first."
204- else :
205- cur .execute ('SELECT * FROM "{}"' .format (args .table ))
212+ if not table_exists (conn , args .table_name ):
213+ results ['status' ] = 1
214+ results ['error' ] = "Cannot find replication status table. Run 'osm2pgsql-replication init' first."
215+ else :
216+ with conn .cursor () as cur :
217+ cur .execute (sql .SQL ('SELECT * FROM {}' ).format (args .table ))
206218 if cur .rowcount != 1 :
207219 results ['status' ] = 2
208220 results ['error' ] = "Updates not set up correctly. Run 'osm2pgsql-updates init' first."
@@ -341,14 +353,13 @@ def update(conn, args):
341353 may be missing in the rare case that the replication service stops responding
342354 after the updates have been downloaded.
343355 """
344- with conn .cursor () as cur :
345- cur .execute ('SELECT * FROM pg_tables where tablename = %s' , (args .table , ))
346- if cur .rowcount < 1 :
347- LOG .fatal ("Cannot find replication status table. "
348- "Run 'osm2pgsql-replication init' first." )
349- return 1
356+ if not table_exists (conn , args .table_name ):
357+ LOG .fatal ("Cannot find replication status table. "
358+ "Run 'osm2pgsql-replication init' first." )
359+ return 1
350360
351- cur .execute ('SELECT * FROM "{}"' .format (args .table ))
361+ with conn .cursor () as cur :
362+ cur .execute (sql .SQL ('SELECT * FROM {}' ).format (args .table ))
352363 if cur .rowcount != 1 :
353364 LOG .fatal ("Updates not set up correctly. Run 'osm2pgsql-updates init' first." )
354365 return 1
@@ -435,7 +446,12 @@ def get_parser():
435446 help = 'Print only error messages' )
436447 group .add_argument ('-v' , '--verbose' , action = 'count' , default = 2 ,
437448 help = 'Increase verboseness of output' )
438- group = default_args .add_argument_group ('Database arguments' )
449+ group = default_args .add_argument_group ('Database arguments' ,
450+ "The following arguments can be used to set the connection parameters to the\n "
451+ "osm2pgsql database. You may also use libpq environment variables to set\n "
452+ "connection parameters, see https://www.postgresql.org/docs/current/libpq-envars.html.\n "
453+ "If your database connection requires a password, use a pgpass file,\n "
454+ "see https://www.postgresql.org/docs/current/libpq-pgpass.html." )
439455 group .add_argument ('-d' , '--database' , metavar = 'DB' ,
440456 help = 'Name of PostgreSQL database to connect to or conninfo string' )
441457 group .add_argument ('-U' , '--username' , metavar = 'NAME' ,
@@ -477,8 +493,8 @@ def get_parser():
477493 help = 'File to save changes before they are applied to osm2pgsql.' )
478494 cmd .add_argument ('--max-diff-size' , type = int , default = 500 ,
479495 help = 'Maximum data to load in MB (default: 500MB)' )
480- cmd .add_argument ('--osm2pgsql-cmd' , default = 'osm2pgsql' ,
481- help = 'Path to osm2pgsql command (default: osm2pgsql)' )
496+ cmd .add_argument ('--osm2pgsql-cmd' , default = INSTALL_PREFIX + 'osm2pgsql' ,
497+ help = f 'Path to osm2pgsql command (default: { INSTALL_PREFIX } osm2pgsql)' )
482498 cmd .add_argument ('--once' , action = 'store_true' ,
483499 help = 'Run updates only once, even when more data is available.' )
484500 cmd .add_argument ('--post-processing' , metavar = 'SCRIPT' ,
@@ -518,17 +534,20 @@ def main():
518534 datefmt = '%Y-%m-%d %H:%M:%S' ,
519535 level = max (4 - args .verbose , 1 ) * 10 )
520536
521- if '"' in args .prefix :
522- LOG .fatal ("Prefix must not contain quotation marks." )
523- return 1
524-
525- args .table = '{}_replication_status' .format (args .prefix )
537+ args .table_name = f'{ args .prefix } _replication_status'
538+ args .table = sql .Identifier (args .table_name )
526539
527540 conn = connect (args )
528- ret = args .handler (conn , args )
529- conn .close ()
530541
531- return ret
542+ try :
543+ if not table_exists (conn , f'{ args .prefix } _ways' ):
544+ LOG .fatal (f'osm2pgsql middle table "{ args .prefix } _ways" not found in database "{ args .database } ". '
545+ 'Database needs to be imported in --slim mode.' )
546+ return 1
547+
548+ return args .handler (conn , args )
549+ finally :
550+ conn .close ()
532551
533552
534553if __name__ == '__main__' :
0 commit comments