2012-02-14 4 views
0

プログラム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は、複数のテーブルを含むSQLiteのデータベースに、元のCSVファイル内のレコードの各タイプごとに1つのファイルに変換しました。ここではFruitColourとなります。

プログラムAのCSVファイルの各テーブルには、一意にする必要のないID主キーがあります。つまり、ID「Orange」とID「Orange」の「Colour」の行を持つ「Fruit」の行があります。

ただし、プログラム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()) 

これは陽気に非効率です。おそらく何らかの種類の表記法を使用して、よりエレガントな/これを行うためのPythonの方法が存在しなければなりません。

また、SQLiteがすべてのテーブルのIDの一意性を強制するように、自分のSQLスキーマ(SQLite風味)を定義できますか?

答えて

1

にこれを維持しますトリガーを使用して日付を返します。私はあなたがそういうことをしたいとは思っていません(それはあなたのデータベースエンジンに依存します)。

重複をチェックするためのより効率的な方法は、配列の代わりにハッシュを使用している:

IDs = {} 

tables = ['Fruit','Colour']; 
for table in tables: 
    rows = db_conn.execute("SELECT ID FROM %s" % table) 
    for row in rows: 
    if IDs.has_key(row['ID']): 
     print "Duplicate ID %s is present in both %s and %s" % (row['ID'], table, IDs[row['ID']]) 
    else: 
     IDs[row['ID']] = table 

キーはそれが勝った3つのテーブルに存在している場合は特にそれは(かなりTE同じ出力を与えるものではありませんすべての順列を表示しないでください)、それはすぐにあなたの問題がどこにあるかを示します。

+0

これはStackOverflowへの最初の貢献です - ようこそ! :)私はこのソリューションがデータを1回通過するだけで済むようにするのが好きです(重複がたくさんある場合、私は 'O(n^2)'です)。 –

+0

さらに考えれば、これは簡単にtriplicates、quadruplicates 1つ以上のテーブル名がハッシュに累積することを可能にすることによって。私。ハッシュキーがすでに存在する場合、ID [row ['ID']] + = table'をハッシュテーブルに挿入します。素敵な出力を生成するためのフィニッシングを少し必要としますが、優れたパフォーマンス特性を維持します。 –

+0

ありがとう:)実際には、IDが2つ以上のテーブルに現れるときに正しい出力を得るのは簡単です:IDを作成するだけです[row ['ID(1) ']]配列を作成し、それにテーブルを追加します(何も印刷しません)。その後、IDハッシュをループし、配列の長さが1より大きいエントリをすべて出力します。 – Claude

0

企業のキーにこの2部構成の記事を参照してください:私はあなたがすべてのIDを持つ別のテーブルを作成しない限り、データベース内でこれを強制するの知っている方法はありません

Primary Key Reengineering Projects by Tom Johnston

+0

私のプロジェクトは、データベースの現場での再設計よりも、データスクラップ作業の本質のほうが多すぎます。 –