2016-05-27 2 views
2

私はPythonにはかなり新しく、これはこの質問に適切な場所でない場合は謝罪します。モジュールを作成してデータベース(psycopg2)の使用を簡略化してください

私はpsycopg2モジュールを使用してPostgreSQLデータベースを操作しています。

# Example 1 

import psycopg2 

conn = psycopg2.connect(database="mydb", user="postgres") 
cur = conn.cursor() 

cur.execute ("SELECT * FROM mytable;") 
rows = cur.fetchall() 
for i, row in enumerate(rows): 
    print "Row", i, "value = ", row 

cur.close() 
conn.close() 

これは、MYDBデータベースへの接続をオープンテーブルからmytableはをすべてのフィールドを選択し、それらを印刷し、接続を閉じます:一般的な使い方は次のようになります。

私が何をしたいのは、これらの関数のいくつかを、多くのスクリプトを通して何度も呼び出す必要があるため、モジュールに取り除くことです。 - 接続を開き、上記のコードの最初の2行で構成さ

  • core.db_init():この例では、理想的には、私は3つの機能を含んでいるコアという名前のモジュールを有することになります。
  • core.db_query(クエリ) - 目的のSQLクエリを実行し、上記のコードの3行目から構成されます。
  • core.db_close() - 接続を閉じ、最後の2行で構成されます。

私は次のようにモジュールを作成しようとした:

# Module core.py 

import psycopg2 

def db_init(): 
    conn = psycopg2.connect(database="mydb", user="postgres") 
    cur = conn.cursor() 

def db_query(query): 
    cur.execute(query) 

def db_close(): 
    cur.close() 
    conn.close() 

しかし、私はこのモジュールを用いて、実施例1を再作成しようとすると、名前空間のエラーを取得:

# Example 2 

import core 

core.db_init() 
core.db_query("SELECT * FROM mytable;") 

rows = cur.fetchall() 
for i, row in enumerate(rows): 
    print "Row", i, "value = ", row  

core.db_close() 

私もありませんよモジュールが実際に私が望むものであることを確かめてください。私は代わりにクラスを使うべきですか?繰り返しますが、私はこれのすべてに対して非常に新しいです。しかし、誰かがこれを行うより良い方法を見つけ出す手助けをすることができたら、私はとても感謝しています。

+0

十分に書かれた質問btwは、あなたが試したことすべて、あなたが望む振る舞い、およそ実際のエラーを持っています。また、StackOverflowへようこそ、特にPythonを歓迎します。)以下の回答のいずれかがあなたの必要性を解決する場合は、質問を「回答済み」としてマークすることを忘れないでください。 – Torxed

答えて

2

あなたの主な問題は、各変数は、あなたがそれを書いた機能に制限されていることである
そうなように宣言なければ:。

def db_init(): 
    global conn 
    conn = psycopg2.... 

がより良いアプローチは、クラスにこれを変換することになり、基本的な例は次のようになります。

import psycopg2 

class MyDatabase(): 
    def __init__(self, db="mydb", user="postgres"): 
     self.conn = psycopg2.connect(database=db, user=user) 
     self.cur = self.conn.cursor() 

    def query(self, query): 
     self.cur.execute(query) 

    def close(self): 
     self.cur.close() 
     self.conn.close() 

db = MyDatabase() 
db.query("SELECT * FROM table;") 
db.close() 

今、あなたはcur.execute()を使用していることから、SELECTクエリはあまりないだろう。
しかし、私はあなたが書いたものに似たコードを保つためにこれを保持していましたが、値を返すことを期待しています。

関数に焦点を当てたアプローチでは、変数がその関数のローカルスコープ内に存在し、他の関数が通常それらにアクセスすることができない場合、 "名前空間"の問題が発生します。

代わりに、クラススコープの変数は、独自の変数にアクセスすることができます。

あなたはグローバル変数を作成し、関数でグローバルとして宣言が、私はコメントで述べたように、私は考えることができます:

あなたがクラスにこれをしたいと思います。データベースは、クラスがセッションエンティティと同じように、セッションベースのエンティティです。それぞれの接続をクラス抽象化して生きたエンティティとして扱います。そうしないと、curとconnはスコープ変数になり、それらをグローバルスコープに渡す必要があります。

+1

ありがとう!私はあなたのクラスアプローチをほぼそのまま使用してしまった。たとえそれがかなりノービッシュだったとしても、私の質問に答える時間を取ってくれて本当にありがとう。暖かい歓迎ありがとうございます:) – fattybake

+0

@fattybakeあなたは歓迎です、そして喜びは私のものです。あなたのような友好的な人々は、与えられた答えに余分な時間を費やす価値があると思っています:)それを維持し、あなたの努力に幸運を! – Torxed

0

私はsqlalchemyまたは他のモジュールを使ってそれらの部分を処理することを検討しますが、それはあなたが望むように行うことができます。

cursorが他の方法で定義されていないため、貼り付けたコードが機能しません。これは最適ではなく、あなたが各1の接続を殺す小さなクエリを多く実行すると、最高のアイデアではないことを

# Module core.py 

import psycopg2 

def execute_query(query): 
    conn = psycopg2.connect(database="mydb", user="postgres") 
    cur = conn.cursor() 
    results = cur.execute(query) 
    cur.close() 
    conn.close() 
    return results 

注:例えば -

は、1回の呼び出しでそれをやって考えてみましょう。

+0

この返答をありがとう!できるだけ私の方法に似ているようにしておきたことに感謝します。あなたが何かをしようとするたびに接続を開いたり閉じたりするので、それは最適ではないということは間違いありません。 Torxedの解決策は、私が必要としていることを正確には知らなかったとしても、私がやろうとしていたことで終わった。 – fattybake

関連する問題