2016-08-25 9 views
1

私はpostgresテーブルを持っています。私はpythonを使ってこれらのテーブルにPostgreSQLスクリプトファイルを実行し、その結果をcsvファイルに書き込みたいと思います。スクリプトファイルにはセミコロンで区切られた複数のクエリがセミコロン;にあります。Pythonを使ったpostgresスクリプトの読み込み

--Duplication Check 
select p.*, c.name 
from scale_polygons_v3 c inner join cartographic_v3 p 
on (metaphone(c.name_displ, 20) LIKE metaphone(p.name, 20)) AND c.kind NOT IN (9,10) 
where ST_Contains(c.geom, p.geom); 

--Area Check 
select sp.areaid,sp.name_displ,p.road_id,p.name 
from scale_polygons_v3 sp, pak_roads_20162207 p 
where st_contains(sp.geom,p.geom) and sp.kind = 1 
and p.areaid != sp.areaid; 

私はPythonのコードを実行すると、それはエラーなしで正常に実行されますが、私は直面しています問題はにクエリの結果を書き込み中に、次のとおりです。サンプルスクリプトは

スクリプトファイルの下に示されていますcsvファイル最後に実行されたクエリの結果のみがcsvファイルに書き込まれます。つまり、最初のクエリー結果は2番目のクエリーで上書きされ、2番目のクエリー結果は3番目にクエリーされ、最後のクエリーまで続きます。ここで

は私のpythonのコードです:

import psycopg2 
import sys 
import csv 
import datetime, time 

def run_sql_file(filename, connection): 
''' 
    The function takes a filename and a connection as input 
    and will run the SQL query on the given connection 
''' 
    start = time.time() 

    file = open(filename, 'r') 
    sql = s = " ".join(file.readlines()) 
    #sql = sql1[3:] 
    print "Start executing: " + " at " + str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M")) + "\n" 
    print "Query:\n", sql + "\n" 
    cursor = connection.cursor() 
    cursor.execute(sql) 
    records = cursor.fetchall() 
    with open('Report.csv', 'a') as f: 
     writer = csv.writer(f, delimiter=',') 
     for row in records: 
      writer.writerow(row) 
    connection.commit() 
    end = time.time() 
    row_count = sum(1 for row in records) 
    print "Done Executing:", filename 
    print "Number of rows returned:", row_count 
    print "Time elapsed to run the query:",str((end - start)*1000) + ' ms' 
    print "\t ===============================" 

def main():  
    connection = psycopg2.connect("host='localhost' dbname='central' user='postgres' password='tpltrakker'") 
    run_sql_file("script.sql", connection) 
    connection.close() 

if __name__ == "__main__": 
    main() 

私のコードが間違っていますか?

+0

おそらく役に立ちませんが、コードは私によく見えます。あなたは[ここ](http://stackoverflow.com/questions/2363731/append-new-row-to-old-csv-file-python)のようにモード 'a'でファイルを開いています – Matthias

+0

1回の呼び出しでは、実行された最後のコマンド(または何かが間違っている場合はエラー)の場​​合にのみ結果が得られます。 – Abelisto

+0

すべてのクエリは同じ数の列を持ち、同じ型(および順序)のクエリですか? –

答えて

1

これは、各クエリを別のファイルとして出力するのが最も簡単です。 copy_expert

query = ''' 
    select p.*, c.name 
    from 
     scale_polygons_v3 c 
     inner join 
     cartographic_v3 p on metaphone(c.name_displ, 20) LIKE metaphone(p.name, 20) and c.kind not in (9,10) 
    where ST_Contains(c.geom, p.geom) 
''' 
copy = "copy ({}) to stdout (format csv)".format(query) 
f = open('Report.csv', 'wb') 
cursor.copy_expert(copy, f, size=8192) 
f.close() 

query = ''' 
    select sp.areaid,sp.name_displ,p.road_id,p.name 
    from scale_polygons_v3 sp, pak_roads_20162207 p 
    where st_contains(sp.geom,p.geom) and sp.kind = 1 and p.areaid != sp.areaid; 
''' 
copy = "copy ({}) to stdout (format csv)".format(query) 
f = open('Report2.csv', 'wb') 
cursor.copy_expert(copy, f, size=8192) 
f.close() 

あなたが同じファイルに第二の出力を追加したい場合は、単にオブジェクトが開かれた最初のファイルを保持します。あなたがここにSQLスクリプトを少し変更することができるならばstdoutからcopy出力はcopy_expert

+0

これは私のために働いたよ、でも私はコードを理解していないので、私はもう少し修正を加えなければなりません –

+1

@ShahzadBachaあなたは '私は答えを更新しました。それ以外の部分はあなたが理解していない? –

+0

実際これは別の質問ですが、どうしたらコードを修正することができますか、クエリから返された行の総数を数え、クエリの最後に 'LIMIT 10 ' –

1

にそれを利用できるようにすることが必要であることを

通知は、回避策です:

#!/usr/bin/env python 

import psycopg2 

script = ''' 
    declare cur1 cursor for 
     select * from (values(1,2),(3,4)) as t(x,y); 

    declare cur2 cursor for 
     select 'a','b','c'; 
    ''' 
print script 

conn = psycopg2.connect(''); 

# Cursors exists and available only inside the transaction 
conn.autocommit = False; 

# Create cursors from script 
conn.cursor().execute(script); 

# Read names of cursors 
cursors = conn.cursor(); 
cursors.execute('select name from pg_cursors;') 
cur_names = cursors.fetchall() 

# Read data from each available cursor 
for cname in cur_names: 
    print cname[0] 
    cur = conn.cursor() 
    cur.execute('fetch all from ' + cname[0]) 
    rows = cur.fetchall() 
    # Here you can save the data to the file 
    print rows 


conn.rollback() 

print 'done' 

免責事項:私はPythonにはまったく初心者です。

関連する問題