@@ -41,7 +41,7 @@ def init_fdw(
41
41
engine : "PostgresEngine" ,
42
42
server_id : str ,
43
43
wrapper : str ,
44
- server_options : Optional [Dict [str , Union [str , None ]]] = None ,
44
+ server_options : Optional [Dict [str , Union [str , int , None ]]] = None ,
45
45
user_options : Optional [Dict [str , str ]] = None ,
46
46
overwrite : bool = True ,
47
47
) -> None :
@@ -67,7 +67,7 @@ def init_fdw(
67
67
if server_options :
68
68
server_keys , server_vals = zip (* server_options .items ())
69
69
create_server += _format_options (server_keys )
70
- engine .run_sql (create_server , server_vals )
70
+ engine .run_sql (create_server , [ str ( v ) for v in server_vals ] )
71
71
else :
72
72
engine .run_sql (create_server )
73
73
@@ -77,7 +77,7 @@ def init_fdw(
77
77
)
78
78
user_keys , user_vals = zip (* user_options .items ())
79
79
create_mapping += _format_options (user_keys )
80
- engine .run_sql (create_mapping , user_vals )
80
+ engine .run_sql (create_mapping , [ str ( v ) for v in user_vals ] )
81
81
82
82
83
83
def _format_options (option_names ):
@@ -178,7 +178,7 @@ def _create_foreign_table(engine, local_schema, table_name, schema_spec, server_
178
178
if server_options :
179
179
server_keys , server_vals = zip (* server_options .items ())
180
180
query += _format_options (server_keys )
181
- engine .run_sql (query , server_vals )
181
+ engine .run_sql (query , [ str ( v ) for v in server_vals ] )
182
182
else :
183
183
engine .run_sql (query )
184
184
@@ -296,6 +296,98 @@ def mount_mysql(
296
296
)
297
297
298
298
299
+ def mount_elasticsearch (
300
+ mountpoint : str ,
301
+ server : str ,
302
+ port : int ,
303
+ username : str ,
304
+ password : str ,
305
+ table_spec : Dict [str , Dict [str , Any ]],
306
+ ):
307
+ """
308
+ Mount an ElasticSearch instance.
309
+
310
+ Mount a set of tables proxying to a remote ElasticSearch index.
311
+
312
+ This uses a fork of postgres-elasticsearch-fdw behind the scenes. You can add a column
313
+ `query` to your table and set it as `query_column` to pass advanced ES queries and aggregations.
314
+ For example:
315
+
316
+ ```
317
+ sgr mount elasticsearch -c elasticsearch:9200 -o@- <<EOF
318
+ {
319
+ "table_spec": {
320
+ "table_1": {
321
+ "schema": {
322
+ "id": "text",
323
+ "@timestamp": "timestamp",
324
+ "query": "text",
325
+ "col_1": "text",
326
+ "col_2": "boolean",
327
+ }
328
+ "index": "index-pattern*",
329
+ "rowid_column": "id",
330
+ "query_column": "query",
331
+ }
332
+ }
333
+ }
334
+ ```
335
+ \b
336
+
337
+ :param mountpoint: Schema to mount the remote into.
338
+ :param server: Database hostname.
339
+ :param port: Database port
340
+ :param username: A read-only user that the database will be accessed as.
341
+ :param password: Password for the read-only user.
342
+ :param table_spec: A dictionary of form
343
+ ```
344
+ {"table_name":
345
+ {"schema": {"col1": "type1"...},
346
+ "index": <es index>,
347
+ "type": <es doc_type, optional in ES7 and later>,
348
+ "query_column": <column to pass ES query in>,
349
+ "score_column": <column to return document score>,
350
+ "scroll_size": <fetch size, default 1000>,
351
+ "scroll_duration": <how long to hold the scroll context open for, default 10m>},
352
+ ...}
353
+ ```
354
+ """
355
+ from splitgraph .engine import get_engine
356
+ from psycopg2 .sql import Identifier , SQL
357
+
358
+ engine = get_engine ()
359
+ logging .info ("Mounting ElasticSearch instance..." )
360
+ server_id = mountpoint + "_server"
361
+
362
+ init_fdw (
363
+ engine ,
364
+ server_id ,
365
+ "multicorn" ,
366
+ {
367
+ "wrapper" : "pg_es_fdw.ElasticsearchFDW" ,
368
+ "host" : server ,
369
+ "port" : port ,
370
+ "username" : username ,
371
+ "password" : password ,
372
+ },
373
+ None ,
374
+ )
375
+
376
+ engine .run_sql (SQL ("CREATE SCHEMA IF NOT EXISTS {}" ).format (Identifier (mountpoint )))
377
+
378
+ for table_name , table_options in table_spec .items ():
379
+ logging .info ("Mounting table %s" , table_name )
380
+ schema = table_options .pop ("schema" )
381
+ _create_foreign_table (
382
+ engine ,
383
+ local_schema = mountpoint ,
384
+ table_name = table_name ,
385
+ schema_spec = schema ,
386
+ server_id = server_id ,
387
+ server_options = table_options ,
388
+ )
389
+
390
+
299
391
def mount (
300
392
mountpoint : str ,
301
393
mount_handler : str ,
0 commit comments