From 8f1bf9a306a09b9b5001ed25c27f953626548d1b Mon Sep 17 00:00:00 2001 From: Gilad Arnold Date: Thu, 13 Oct 2016 11:32:30 -0700 Subject: [PATCH] Fix Postgresql CSV import for older versions. Postresql's COPY command syntax has changed from 8.x to 9.x. odo uses the new syntax, which produces a syntax error when running against 8.x and older. Below is a patch that probes the database version and applies the correct syntax. It also fixes a (suspected) bug in how encoding is inferred. --- odo/backends/sql_csv.py | 75 +++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 26 deletions(-) diff --git a/odo/backends/sql_csv.py b/odo/backends/sql_csv.py index d2277e51..a5b31ee8 100644 --- a/odo/backends/sql_csv.py +++ b/odo/backends/sql_csv.py @@ -151,32 +151,55 @@ def compile_from_csv_postgres(element, compiler, **kwargs): raise ValueError( r'PostgreSQL does not support line terminators other than \n' ) - return compiler.process( - sa.text( - """ - COPY {0} FROM :path ( - FORMAT CSV, - DELIMITER :delimiter, - NULL :na_value, - QUOTE :quotechar, - ESCAPE :escapechar, - HEADER :header, - ENCODING :encoding - ) - """.format(compiler.preparer.format_table(element.element)) - ).bindparams( - path=os.path.abspath(element.csv.path), - delimiter=element.delimiter, - na_value=element.na_value, - quotechar=element.quotechar, - escapechar=element.escapechar, - header=element.header, - encoding=element.encoding or element.bind( - 'show client_encoding' - ).execute().scalar() - ), - **kwargs - ) + postgres_version = element.bind.execute('select version()').scalar() + if int(postgres_version.split()[1].split('.')[0]) >= 9: + return compiler.process( + sa.text( + """ + COPY {0} FROM :path ( + FORMAT CSV, + DELIMITER :delimiter, + NULL :na_value, + QUOTE :quotechar, + ESCAPE :escapechar, + HEADER :header, + ENCODING :encoding + ) + """.format(compiler.preparer.format_table(element.element)) + ).bindparams( + path=os.path.abspath(element.csv.path), + delimiter=element.delimiter, + na_value=element.na_value, + quotechar=element.quotechar, + escapechar=element.escapechar, + header=element.header, + encoding=element.encoding or element.bind.execute( + 'show client_encoding' + ).scalar() + ), + **kwargs + ) + else: + return compiler.process( + sa.text(( + """ + COPY {0} FROM :path + NULL :na_value + DELIMITER :delimiter + CSV %s + QUOTE :quotechar + ESCAPE :escapechar + """ % ('HEADER' if element.header else '') + ).format(compiler.preparer.format_table(element.element)) + ).bindparams( + path=os.path.abspath(element.csv.path), + delimiter=element.delimiter, + na_value=element.na_value, + quotechar=element.quotechar, + escapechar=element.escapechar, + ), + **kwargs + ) try: