我正在進行從程序A的CSV格式到程序B的CSV格式的數據格式轉換。加強/檢查多個表中主鍵的唯一性
計劃A的格式如下:
Fruit, Orange, $1.99
Fruit, Apple, $2.99
Fruit, Pear, $5.99
Colour, Red, #FF0000
Colour, Green, #00FF00
Colour, Blue, #0000FF
Colour, Orange, #FF8800
我已經轉換計劃A的CSV文件導入包含多個表,一個是在原來的CSV文件中每種類型的記錄的SQLite數據庫。這裏是Fruit
和Colour
。這很好映射到程序B的文件格式,該文件格式使用類似的表格(需要幾個時髦的轉換)。
程序A的CSV文件中的每個表都有一個不需要唯一的ID主鍵。也就是說,可以存在ID爲「Orange
」的「Fruit
」行和ID爲「Orange
」的「Colour
」行。
但是,程序B會認爲這是一個錯誤 - 它要求ID主鍵在所有表中都是唯一的。
在原始文件(格式如上)或SQL數據庫中,檢測非唯一ID密鑰的有效方法是什麼?有幾十個表格和數千個記錄。
我目前的做法是類似(Python代碼):
import sqlite3, collections
db_conn = sqlite3.connect('db.sqlite3')
db_conn.row_factory = sqlite3.Row
IDs = [] # build a list of (ID, table_name) pairs
tables = ['Fruit','Colour'];
for table in tables:
rows = db_conn.execute("SELECT ID FROM %s" % table)
for row in rows:
IDs.append((row['ID'],table))
id_counts = collections.Counter([x(0) for x in IDs])
duplicated_ids = [x for x in id_counts if id_counts[x] > 1]
for duplicated_id in duplicated_ids:
duplicated_types = [x(1) for x in IDs if x(0) == duplicated_id ]
print ("Duplicate ID %(duplicated_id)s used for %(duplicated_types)s" % locals())
這似乎歡快效率低下。必須有一個更優雅/更Pythonic的方式來做到這一點,可能使用某種設置符號。
或者,我可以定義我的SQL模式(SQLite風格),以便SQLite強制所有表的ID的唯一性?
這是搖滾樂對StackOverflow的第一個貢獻 - 歡迎! :)我喜歡這個解決方案只需要一次通過數據(如果有很多重複項,我的是'O(n^2)'。) – 2012-02-14 09:26:11
在進一步的思考中,這可以很容易地擴展到報告一式三份,一式四份等等,通過允許多個表名稱在散列中累積。即如果散列鍵已經存在,則將'IDs [row ['ID']] + = table'插入散列表。需要一點點生產好的輸出,但保持良好的性能特點。 – 2012-02-14 09:34:35
謝謝:)。請注意,哈希函數是O(1),所以這個解決方案的確是O(n) 事實上,當ID出現在兩個以上的表中時,應該很容易得到正確的輸出:只需將ID [row ['ID ']]數組並添加表格(不打印任何內容)。然後循環通過ID散列並打印數組長度超過1的任何條目。 – Claude 2012-02-14 10:03:27