Обеспечить / проверить уникальность первичного ключа в нескольких таблицах - PullRequest
0 голосов
/ 14 февраля 2012

Я выполняю преобразование формата данных из формата программы CSV в формат программы B.

Формат программы 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

Я преобразовал файл CSV программы A в базу данных SQLite, содержащую несколько таблиц, по одной для каждого типа записи в исходном файле CSV. Здесь это будет Fruit и Colour. Это хорошо отображает формат файла Программы B, в котором используются аналогичные таблицы (с некоторыми необходимыми преобразованиями).

Каждая таблица в файле CSV программы A имеет первичный ключ ID, который не обязательно должен быть уникальным. То есть может быть строка "Fruit" с идентификатором "Orange", а также строка "Colour" с идентификатором "Orange".

Однако программа B считает это ошибкой - требуется, чтобы первичный ключ идентификатора был уникальным во всех таблицах.

Как эффективный способ обнаружить неуникальные ключи идентификаторов, либо в исходном файле (отформатированном как указано выше), либо в базе данных SQL? Есть десятки таблиц и тысячи записей.

Мой текущий подход похож на (код 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 обеспечивал уникальность идентификатора для всех таблиц?

Ответы [ 2 ]

1 голос
/ 14 февраля 2012

Я не знаю, как это реализовать в базе данных, если только вы не создадите другую таблицу со всеми идентификаторами, обновляйте ее с помощью триггеров.Я не уверен, что вы когда-нибудь захотите сделать что-то подобное (возможно ли это вообще зависит от вашего движка базы данных).

Более эффективный способ проверки на наличие дубликатов - использование хэша вместо массива:

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 таблицах, он не показывает все перестановки), но он быстро покажет вам, где ваши проблемы.

0 голосов
/ 14 февраля 2012

См. Эту статью из двух частей о корпоративных ключах:

Проекты по реинжинирингу первичных ключей от Tom Johnston

...