2012-11-14 17 views
8

mysqlに接続するPythonプログラムを作成しています。私は、テーブルには、それが正常に接続されたことを示すために、数字の1が含まれているかどうかを確認する必要がありPython MySQdbでレコードが存在するかどうかをチェックする方法

が、これはこれまでの私のコードです:

xcnx.execute('CREATE TABLE settings(status INT(1) NOT NULL)') 
    xcnx.execute('INSERT INTO settings(status) VALUES(1)') 
    cnx.commit() 
    sqlq = "SELECT * FROM settings WHERE status = '1'" 
    xcnx.execute(sqlq) 
    results = xcnx.fetchall() 
    if results =='1': 
    print 'yep its connected' 
    else: 
    print 'nope not connected' 

私が見逃している何?私はSQLのnoobです、ありがとう男。

+0

よりも優れていますデータベースに接続できること、またはテーブルを作成してデータを挿入できることを確認する – jdi

+0

いいえ私は作成と挿入を接続できることを知っています。レコードが存在するかどうかを確認して確認する方法を知る必要があります。 –

答えて

14

私は、クエリがちょうどcountを行うことです「それは存在しない」最も効率的と考えている:

sqlq = "SELECT COUNT(1) FROM settings WHERE status = '1'" 
xcnx.execute(sqlq) 
if xcnx.fetchone()[0]: 
    # exists 

代わりのフィールドまたは列の任意の数の操作を実行するためにデータベースを求めて、あなただけにそれを求めています結果が一致する場合は1または0を返します。実際のレコードを返すだけでなく、クライアント側でのシリアライズとデシリアライゼーションとデータ転送を節約できるので、これはずっと効率的です。

In [22]: c.execute("select count(1) from settings where status = 1") 
Out[22]: 1L # rows 

In [23]: c.fetchone()[0] 
Out[23]: 1L # count found a match 

In [24]: c.execute("select count(1) from settings where status = 2") 
Out[24]: 1L # rows 

In [25]: c.fetchone()[0] 
Out[25]: 0L # count did not find a match 

count(*)count(1)と同じになるだろう。あなたのケースでは、新しいテーブルを作成しているので、1つの結果が表示されます。 10,000回の試合がある場合は10000になります。しかし、あなたのテストで気になるのは、0でないかどうかということですので、bool真理テストを実行できます。

In [15]: if c.execute("select (1) from settings where status = 1 limit 1"): 
      print True 
True 

In [16]: if c.execute("select (1) from settings where status = 10 limit 1"): 
      print True 

In [17]: 

これは、DjangoのORMはqueryObject.exists()を行う方法もある。

更新

実は、それだけで行数を使用し、さらにその結果をフェッチしないで、さらに高速です。

+0

私はあなたの方法に間違いなく同意しますが、それ以外の状況でも使用しますが、不一致の場合でも 'COUNT(*)'は実際に行が返される奇妙なケースです(行には番号0)。 – RocketDonkey

+0

@RocketDonkey:私は、クエリの存在をチェックするために可能な最小限の処理を使用するように私の例を修正しました。 'count(1)'を行うことはさらに小さくなります。そして、あなたは単一のintの最初の結果をチェックします。 – jdi

+0

+1、あなたは私の投票を得る:) – RocketDonkey

1

results = xcnx.fetchall()を実行すると、戻り値は行の値を含むタプルのシーケンスです。したがって、results == '1'かどうかを確認するときに、シーケンスを定数と比較しようとしています。これはFalseを返します。あなたはこれを試すことができるようにあなたのケースでは、値0の単一の行は、返されます。

results = xcnx.fetchall() 
# Get the value of the returned row, which will be 0 with a non-match 
if results[0][0]: 
    print 'yep its connected' 
else: 
    print 'nope not connected' 

(カーソルを作成する際に.cursor(MySQLdb.cursors.DictCursorを使用し、)あなたが代わりに物事が少し簡単になるだろうどのDictCursorを使用することができますcodewiseを解釈するが、結果は同じです。

if results[0]['COUNT(*)]': 
    # Continues... 

また、この場合ではない大したことが、あなたは文字列に整数値を比較しています。 MySQLは型変換を行いますが、SELECT COUNT(*) FROM settings WHERE status = 1を使用して(非常に小さい)ビットの処理を保存することができます。

2

接続が正常に確立されているかどうかを確認してから、テーブルを作成し、行を挿入してからデータを取得しようとしているのはなぜですか?これまでにあなたが成功した接続が確立されていることを示しているあなたのプログラムが例外をスローしていない場合

あなたは、単に実際には、次の...

sqlq = "SELECT * FROM settings WHERE status = '1'" 
xcnx.execute(sqlq) 
results = xcnx.fetchone() 
if results =='1': 
    print 'yep its connected' 
else: 
    print 'nope not connected' 

を行うことができます。 (上記のコードをチェックしてください。この場合、fetchoneがタプル、文字列、またはintを返すかどうかはわかりません)。

ところで、何らかの理由でテーブルを作成する必要がある場合は、プログラムを正常に実行できるように終了する前にテーブルを削除することをお勧めします。

0

私は最近selectをクエリするのではなく、ユニークな列にプライマリインデックスを追加して追加するだけで効率が向上しました。 MySQLは存在しない場合にのみ追加します。

ので、代わりの2文:

Query MySQL for exists: 
    Query MySQL insert data 

はわずか1を行うと、それはユニークだ場合にのみ動作します:

Query MySQL insert data 

1クエリはあなただけしたいです2.

関連する問題