I want to write a script in Python that creates a PostgreSQL table from a CSV. Instead of using psycopg2.copy_from
I want something more personal and more flexible.
Obviously, I am going to read the first row of the CSV file and get a list of column names from it. Then I want to transform this list into the list of columns that you would write when creating a table in postgreSQL :
"column_name_1" text,
"column_name_2" text,
"column_name_3" text,
...
"column_name_N" text
(by default, I want all my columns to have the type text ; I may change these types later). Note that I DO want the double quotes around the column names to appear, since these column names may contain spaces or accented characters.
I tried to use psycopg2.sql.Identifier
to put double quotes around my column names, but it fails since I want to concatenate these identifiers with "text"...
Here is what I tried so far:
import psycopg2
import csv
conn = psycopg2.connect(
dbname = "spatialDB",host="localhost",
port = 5432, user = "postgres",
password="postgres"
)
cur = conn.cursor()
FileName = "csv_to_import.csv"
file = open(FileName,'r',encoding='utf-8')
reader = csv.reader(file,delimiter=";")
columns = next(reader)
# The line below is what I wanted to do, but you cannot concatenate
# an SQL identifier with a string
#column_types = [psycopg2.sql.Identifier(c) + " text" for c in colums]
# This is what I did instead but it's ugly
column_types = ["\"" + c + "\" text" for c in columns]
schema = "myschema"
table_name = "import_csv_python"
model_query = "CREATE TABLE {0}.{1}({2});"
column_list = ",".join(column_types)
query = model_query.format(schema,table_name,column_list)
cur.execute(query)
file.close()
cur.close()
conn.commit()
How would you correct this code to make it use the psycopg2.sql.Identifier function, to properly quote the column names? (the same question goes for the parameters {0} and {1}, which are respectively the schema and the table name)
Use the method as_string(context)
to build the columns list and convert all string arguments to Composable:
import psycopg2.sql as sql
column_types = [sql.Identifier(c).as_string(cur) + " text" for c in columns]
schema = sql.Identifier("myschema")
table_name = sql.Identifier("import_csv_python")
model_query = sql.SQL("CREATE TABLE {0}.{1}({2});")
column_list = sql.SQL(",".join(column_types))
query = model_query.format(schema,table_name,column_list)