составной ключ в web2py - PullRequest
       7

составной ключ в web2py

2 голосов
/ 13 марта 2012

У меня есть таблица, определенная в web2py

db.define_table(
'pairing',
Field('user',writable=True,readable=True),
Field('uid', writable=True , readable=True)
)

В этой таблице должна быть уникальная комбинация пользователя и идентификатора пользователя.Я просмотрел документацию web2py, но нет прямого способа определить составной ключ.Как мы определяем составной путь в web2py

Ответы [ 2 ]

9 голосов
/ 13 марта 2012

Это зависит от того, что вы пытаетесь сделать. По умолчанию web2py автоматически создает автоматически увеличивающееся поле id, которое будет служить первичным ключом для каждой таблицы, и это рекомендуемый подход, когда это возможно. Если вы имеете дело с устаревшей базой данных с составными первичными ключами и не можете изменить схему, вы можете указать атрибут primarykey, хотя с некоторыми ограничениями (как объяснено здесь ):

db.define_table('pairing', 
    Field('user', writable=True, readable=True), 
    Field('uid', writable=True, readable=True),
    primarykey=['user', 'uid'])

Возможно, вместо этого вам действительно не нужен настоящий составной первичный ключ, но вам просто нужен какой-то способ, чтобы гарантировать, что в таблицу будут вставлены только уникальные пары значений user / uid. В этом случае вы можете сделать это, указав правильно построенный валидатор IS_NOT_IN_DB для одного из двух полей:

db.define_table('pairing',
    Field('user', writable=True, readable=True),
    Field('uid', writable=True, readable=True))

db.pairing.uid.requires=IS_NOT_IN_DB(db(db.pairing.user==request.vars.user),
    'pairing.uid')

Это обеспечит уникальность uid среди набора записей, где user соответствует вставляемому новому значению user (поэтому комбинация user и uid должна быть уникальной). Обратите внимание, что валидаторы (такие как IS_NOT_IN_DB) применяются только тогда, когда значения вставляются с помощью SQLFORM или с использованием метода .validate_and_insert(), поэтому вышеприведенное не будет работать для произвольных вставок в таблицу, но в первую очередь предназначено для ввода данных пользователем. .

Вы также можете использовать SQL, чтобы установить уникальное ограничение для нескольких столбцов таблицы (что можно сделать непосредственно в базе данных или с помощью метода web2py .executesql()). Однако даже с таким ограничением вы все равно захотите выполнить некоторую проверку входных данных в вашем приложении, чтобы избежать ошибок в базе данных.

3 голосов
/ 23 января 2013

Я использовал вычисляемое поле для создания / симуляции составного ключа.Взяв пример из приведенного выше вопроса, можно определить таблицу соединений следующим образом:

from md5 import md5
db.define_table( 'pairing',
                 Field('user', writable=True, readable=True),
                 Field('uid', writable=True, readable=True),
                 Field( 'user_uid_md5', 
                        length=32,
                        unique=True,
                        writable=False,
                        readable=False,
                        compute=lambda row: md5("{0}:{1}".format(row.user,row.uid)).hexdigest()))

Поле user_uid_md5 автоматически вычисляется при вставке и обновлении.Значение этого поля - хеш md5 строки, полученной из двух полей user и uid.Это поле также помечено как unique.Таким образом, база данных обеспечивает уникальность здесь, и это работает вокруг ограничения, указанного Энтони .Это также должно работать для эмуляции составных ключей с более чем двумя полями.Если вы видите какие-либо пробелы в этом подходе, пожалуйста, дайте мне знать.

Редактировать: Небольшое обновление способа вычисления хеша md5 для учета случая, указанного Чен Леви в комментарии ниже.

...