我想用Python编写一个从CSV创建PostgreSQL表的脚本。与其使用psycopg2.copy_from
,而是希望我提供更个性化,更灵活的功能。
很显然,我将读取CSV文件的第一行并从中获取列名称的列表。然后我想将此列表转换为在postgreSQL中创建表时要编写的列列表:
"column_name_1" text,
"column_name_2" text,
"column_name_3" text,
...
"column_name_N" text
(默认情况下,我希望我的所有列都具有文本类型;稍后可能会更改这些类型)。 请注意,我确实希望在列名周围出现双引号,因为这些列名可能包含空格或带重音的字符。
我尝试使用psycopg2.sql.Identifier
在列名两边加上双引号,但是失败了,因为我想将这些标识符与“文本”连接起来。
这是我到目前为止尝试过的:
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()
您如何纠正此代码以使其使用psycopg2.sql.Identifier函数正确引用列名? (对于参数{0}和{1},分别是模式和表名,也有同样的问题)
答案 0 :(得分:1)
使用方法as_string(context)
构建列列表,并将所有字符串参数转换为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)