2014-01-15 79 views
0

現在我正在處理一個帶有數據庫的項目。當我刪除一些行時,我想讓它重置,因此它們之間沒有間隔。 這是我想要的一個例子。python sqlite3 - 如何刪除一些行後重置INTEGER PRIMARY KEY ID的值

當前數據庫。

ID: 1 Date: Date Exercise: Squat Sets: 3 Reps: 3 Weight: 3.0 
ID: 2 Date: Date Exercise: Squat Sets: 3 Reps: 3 Weight: 3.0 
ID: 3 Date: Date Exercise: Squat Sets: 1 Reps: 2 Weight: 3.0 
ID: 4 Date: Date Exercise: Squat Sets: 1 Reps: 2 Weight: 3.0 
ID: 5 Date: Date Exercise: Squat Sets: 1 Reps: 2 Weight: 3.0 
ID: 6 Date: Date Exercise: Squat Sets: 1 Reps: 2 Weight: 3.0 
ID: 7 Date: Date Exercise: Squat Sets: 1 Reps: 1 Weight: 4.0 
ID: 8 Date: Date Exercise: Squat Sets: 1 Reps: 1 Weight: 4.0 
ID: 9 Date: Date Exercise: Squat Sets: 1 Reps: 1 Weight: 4.0 
ID: 10 Date: Date Exercise: Squat Sets: 1 Reps: 1 Weight: 4.0 

刪除行3到7,將產生......

ID: 1 Date: Date Exercise: Squat Sets: 3 Reps: 3 Weight: 3.0 
ID: 2 Date: Date Exercise: Squat Sets: 3 Reps: 3 Weight: 3.0 
ID: 8 Date: Date Exercise: Squat Sets: 1 Reps: 1 Weight: 4.0 
ID: 9 Date: Date Exercise: Squat Sets: 1 Reps: 1 Weight: 4.0 
ID: 10 Date: Date Exercise: Squat Sets: 1 Reps: 1 Weight: 4.0 

這就是我希望它是.....

ID: 1 Date: Date Exercise: Squat Sets: 3 Reps: 3 Weight: 3.0 
ID: 2 Date: Date Exercise: Squat Sets: 3 Reps: 3 Weight: 3.0 
ID: 3 Date: Date Exercise: Squat Sets: 1 Reps: 1 Weight: 4.0 
ID: 4 Date: Date Exercise: Squat Sets: 1 Reps: 1 Weight: 4.0 
ID: 5 Date: Date Exercise: Squat Sets: 1 Reps: 1 Weight: 4.0 

這裏是功能我目前有...

def delete_range(self): 
     """ 
     Deletes a range of rows in the SQL events table. The range is determined by entries in the starting and ending 
     DeleteRowEntry entries. 
     """ 
     starting_index = int(self.startingRowEntry.get()) 
     ending_index = int(self.endingRowEntry.get()) 

     conn = lite.connect('fit.db') 
     cursor = conn.cursor() 
     cursor.execute("""DELETE FROM events WHERE(id >= (?)) 
            AND (id <= (?))""",(starting_index,ending_index)) 
     cursor.execute("""DELETE FROM SQLITE_SEQUENCE WHERE NAME = 'events'""") 
     conn.commit() 
     conn.close 

這裏的設置爲我正在進行操作。

cursor.execute('''CREATE TABLE IF NOT EXISTS events(id INTEGER PRIMARY KEY , date text, exercise_id int, sets int, reps int, weight real)''') 
+0

爲什麼用MySQL標記它,當它是一個關於SQLite的問題? – DopeGhoti

+0

我以爲他們是一樣的東西哈哈(:(),編輯它 – user2980081

+2

你爲什麼要這樣做?如果在其他表或數據庫之外的任何引用這些ID,你真的**希望他們保持穩定。 –

回答

1

你會更新所有行後ending_index基於ending_indexstarting_index之間的增量有一個新的id

cursor.execute("""UPDATE events SET id=id - ? WHERE id > ?""", 
       ((ending_index - starting_index) + 1, ending_index)) 

不要從SQLITE_SEQUENCE表中刪除events行要麼;相反,在上述UPDATE之後用MAX(id)events更新它。

但你正常真的不想這樣做;其他表和外部系統預計PRIMARY KEY行ID保持穩定。

如果您擔心用戶被事件id中的空白所困惑,那麼請不要向最終用戶顯示這些ID。您始終可以按順序在GUI中對可見行進行編號,但仍然會分別跟蹤實際的數據庫ID。

+0

不錯;這是我的#2,寫得很乾淨,而不是很糟糕的解釋。 :) – abarnert

0

這幾乎肯定是一個非常糟糕的主意 - 關鍵的關鍵在於它們是引用記錄的穩定方法(在另一個採用外鍵或應用程序等中)。

但如果你真的想要,只是遍歷在ID順序行並將它們設置爲「正確」的價值觀,像這樣:

cursor.execute('SELECT id FROM events ORDER BY id') 
inner_cursor = db.cursor() 
for i, row in enumerate(cursor): 
    inner.execute('UPDATE events SET id = ? WHERE id = ?', i, row[0]) 

您可以通過兩種方式優化這樣的:

  1. 不要在每次修改之後進行修改,而只能在批次中的最後一個之後修改。
  2. 如果您在每次修改後都進行修改,只需修改ending_index後的修改,然後使用單個UPDATE將每個修改爲id - gap
+0

謝謝你,在閱讀了你的意見和其他一些意見之後,我不會去解決它,我認爲這將是一個好主意!我充滿了這些不好的想法哈哈! – user2980081

相關問題