2015-08-28 63 views
0

我在Python中編寫了下面的代碼,連接到DB,創建兩個表並將它們連接起來。然後它打印JOIN查詢的結果。Python腳本中JOIN查詢返回的行數不正確

問題是,行數是3,但我預計會得到2行。此外,如果我運行使用sqlite>在命令提示相同的查詢,那麼由JOIN返回的行數是正確的,即2.

import sqlite3 as lite 
import pandas as pd 

# Connecting to the database. The `connect()` method returns a connection object. 
con = lite.connect('getting_started.db') 

with con: 
    cur = con.cursor() 
    cur.execute("DROP TABLE IF EXISTS cities") 
    cur.execute("DROP TABLE IF EXISTS weather") 

    cur.execute("CREATE TABLE cities (name text, state text)") 
    cur.execute("CREATE TABLE weather (city text, year integer, warm_month text, cold_month text, average_high integer)") 

    # Filling 'cities' with the data 
    cur.execute("INSERT INTO cities VALUES('Washington', 'DC')") 
    cur.execute("INSERT INTO cities VALUES('Houston', 'TX')") 

    # Filling 'weather' with the data 
    cur.execute("INSERT INTO weather VALUES('Washington', 2013, 'July', 'January', 59)") 
    cur.execute("INSERT INTO weather VALUES('Houston', 2013, 'July', 'January', 62)") 

    # Joining data together 
    sql = "SELECT name, state, year, warm_month, cold_month FROM cities " \ 
      "INNER JOIN weather " \ 
      "ON name = city" 
    cur.execute(sql) 

rows = cur.fetchall() 
cols = [desc[0] for desc in cur.description] 

# Loading data into pandas 
df = pd.DataFrame(rows, columns=cols) 

for index, row in df.iterrows(): 
    print("City: {0}, The warmest month: {1}".format(row['name'],row['warm_month'])) 

在Python結果是:

City: Washington, The warmest month: July 
City: Washington, The warmest month: July 
City: Houston, The warmest month: July 

然而,在命令提示符的結果是不同的(正確的):

City: Washington, The warmest month: July 
City: Houston, The warmest month: July 
+0

你能告訴我們它返回的3行嗎?例如。 'print(rows)' –

+0

@Tom Dalton:我更新了這篇文章,請檢查一下。 –

+2

我注意到的一件事是'rows = cur ....'行在'with con:'context manager之外。我不認爲這應該有所作爲,但可能值得修復。 –

回答

2

的問題是,你的rows = cur.fetchall()是外10連接上下文管理器,所以當你使用光標時,發生了一些奇怪的事情,並且它的數據庫連接已關閉。

請參考這裏的文檔:https://docs.python.org/2/library/sqlite3.html#using-the-connection-as-a-context-manager它暗示with con:提供了一個事務,它可能解釋奇怪的行爲在事務中執行語句,但然後試圖在事務外的結果集上使用遊標。

對我來說,這仍然顯得很奇怪,我本以爲這種使用會導致sqllite3引發一個異常,告訴你這種情況正在發生。