我使用psycopg2從我用 Python 撰寫的程式中呼叫 PostgreSQLCOPY命令,到目前為止,我已經使用copy_from該包中的函式來實作這一點。據我了解,在最近的版本中,表的限定名稱,也就是說,出于安全原因(SQL 注入)scheman_name.table_name使用時不再被授權。copy_from根據我在他們的 Github 頁面上讀到的內容,顯然copy_expert是今后尋找合格名稱的方法。我試圖相應地調整我的程式,但出現語法錯誤。這里我提供一個測驗用例。
假設這是我的表(假設這dev_schema是一個已經存在的模式):
create table dev_schema.testtab(numval integer not null);
以及我們要匯入到這個表中的資料檔案: Data.txt
100
120
200
800
500
要將上述檔案通過 直接匯入表中psql,我所要做的就是在psql提示符下運行以下命令:
\copy dev_schema.testtab from 'D:/Data.txt' with (format CSV, NULL '', delimiter '|', quote '"');
我的目的是使用psycopg2.copy_expert.
這是我的程式:
import psycopg2
from psycopg2 import sql
def main():
connection = psycopg2.connect(
dbname="testdb",
user="dev_user",
password="Here I write my password",
host="localhost",
port=5432
)
#
# Create a cursor
cursor = connection.cursor()
#
#
# Importing the data file
filepath = "D:/Data.txt"
with open(
file=filepath,
mode="r",
encoding="UTF-8"
) as file_desc:
option_values = [
"format CSV",
"NULL ''",
"delimiter '|'",
"quote '\"'"
]
copy_options = sql.SQL(', ').join(
sql.Identifier(n) for n in option_values
)
cursor.copy_expert(
sql=sql.SQL(
"copy {} from stdin with ({})"
).format(
sql.Identifier("dev_schema", "testtab"),
copy_options
),
file=file_desc
)
cursor.close()
connection.close()
print("done")
if __name__ == "__main__":
main()
但是當我運行這個程式時,我收到以下錯誤訊息:
cursor.copy_expert(
psycopg2.errors.SyntaxError: ERROR: option ? format CSV ? not recognized
LINE 1: copy "dev_schema"."testtab" from stdin with ("format CSV", "...
但我看不出選項有什么問題,因為當我直接在提示中CSV使用時它作業得很好。\copypsql
你能澄清一下嗎?提前致謝
編輯: 根據 Adrian Klaver 的評論,我相應地更改了我的代碼,將所有選項直接作為字串包含在末尾,但現在我收到一條新的錯誤訊息:
psycopg2.errors.SyntaxError: ERROR : Syntax error on or near 'dev_schema'
LINE 1: copy Identifier('dev_schema', 'testtab') from stdin with (fo...
這是我的代碼的新版本:
import psycopg2
from psycopg2 import sql
def main():
connection = psycopg2.connect(
dbname="testdb",
user="dev_user",
password="Here I write my password",
host="localhost",
port=5432
)
#
# Create a cursor
cursor = connection.cursor()
#
#
# Importing the data file
filepath = "D:/Data.txt"
with open(
file=filepath,
mode="r",
encoding="UTF-8"
) as file_desc:
option_values = "".join(
[
"format CSV, ",
"NULL '', ",
"delimiter '|', ",
"quote '\"',"
]
)
cursor.copy_expert(
sql=sql.SQL("".join(
[
"copy {} from stdin with (",
option_values,
")"
]).format(sql.Identifier("dev_schema", "testtab"))
),
file=file_desc
)
cursor.close()
connection.close()
print("done")
if __name__ == "__main__":
main()
uj5u.com熱心網友回復:
一般提示。將組合查詢分配給變數并列印它以查看問題所在。
copy_cmd = sql.SQL(
"copy {} from stdin with ({})"
).format(
sql.Identifier("dev_schema", "testtab"),
copy_options
)
print(copy_cmd.as_string(connection))
當然,copy_options應該構建為純文本,而不是識別符號串列:
with open(
file=filepath,
mode="r",
encoding="UTF-8"
) as file_desc:
option_values = [
"format CSV",
"NULL ''",
"delimiter '|'",
"quote '\"'"
]
copy_options = sql.SQL(', '.join(
n for n in option_values)
)
copy_cmd = sql.SQL(
"copy {} from stdin with ({})"
).format(
sql.Identifier("dev_schema", "testtab"),
copy_options
)
# print(copy_cmd.as_string(connection))
cursor.copy_expert(
sql=copy_cmd,
file=file_desc
)
connection.commit() # !!!
connection.close()
不要忘記承諾!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/529225.html
上一篇:在沒有COMMITpostgresql的情況下關閉的客戶端發起的事務
下一篇:角度組件的重繪問題
