1

Python の csv.writer で生成した .csv ファイルを bcp しようとすると、EOF の問題が発生します。私は運が悪かったので、たくさんのグーグルをやったので、SOの親切な人々に頼ります

エラーメッセージは次のとおりです(subprocess.call()行でトリガーされます):

Starting copy...
Unexpected EOF encountered in BCP data-file.
bcp copy in failed

コードは次のとおりです。

sel_str = 'select blahblahblah...'
result = engine.execute(sel_str)  #engine is a SQLAlchemy engine instance

# write to disk temporarily to be able to bcp the results to the db temp table
with open('tempscratch.csv','wb') as temp_bcp_file:
    csvw = csv.writer(temp_bcp_file)
    for r in result:
        csvw.writerow(r)
        temp_bcp_file.flush()

# upload the temp scratch file
bcp_string = 'bcp tempdb..collection in @INFILE -c -U username -P password -S DSN'
bcp_string = string.replace(bcp_string,'@INFILE','tempscratch.csv')
result_code = subprocess.call(bcp_string, shell=True)

テキスト エディターで tempscratch.csv ファイルを確認しましたが、奇妙な EOF やその他の制御文字は見当たりませんでした。さらに、比較のために他の .csv ファイルを調べましたが、bcp が探している標準化された EOF はないようです。

また、はい、これはハッキーです。結果セットを取得し、ディスクに書き込み、bcp を使用してデータベースに再アップロードします。SQLAlchemy は同じ execute() コマンドで複数行のステートメント (別名 DDL および DML) をサポートしていないため、これを行う必要があります。さらに、この接続は、SQLAlchemy のすばらしい ORM をサポートしていない Sybase db との接続です:( (これが、最初に execute() を使用している理由です)

4

1 に答える 1

5

私が知る限り、bcp のデフォルトのフィールド区切り文字はタブ文字 '\t' ですが、Python の csv ライターのデフォルトはカンマです。これを試して...

# write to disk temporarily to be able to bcp the results to the db temp table
with open('tempscratch.csv','wb') as temp_bcp_file:
    csvw = csv.writer(temp_bcp_file, delimiter = '\t')
    for r in result:
        csvw.writerow(r)
    temp_bcp_file.flush()
于 2012-05-24T15:42:32.517 に答える