peewee manytomany - идентификатор объекта и идентификатор объекта b через таблицу вызывают ошибку целостности - PullRequest
0 голосов
/ 26 октября 2019

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

path = ['div', 'div', 'div', 'div', 'div', 'ul', 'li', 'a']

ЕслиПуть выше имеет идентификатор 1, и я сохраняю теги с уникальным ограничением. Ожидается следующее в сквозной таблице:

  • path_id |tag_id
  • 1 ______ 1
  • 1 ______ 1
  • 1 ______ 1
  • 1 ______ 1
  • 1 ______ 1
  • 1 ______ 2
  • 1 ______ 3
  • 1 ______ 4

Где 1, 3, 3 и 4 tag_id равны div, ul, li и a соответственно.

Однако я получаю следующую ошибку:

peewee.IntegrityError: UNIQUE constraint failed: path_tag_through.path_id, path_tag_through.tag_id

Что именно я здесь не так делаю? Я также не могу установить unique=False.

Вот код для репликации:

import peewee
from peewee import *
db = SqliteDatabase('bs.db')

class BaseModel(Model):
    class Meta:
        database = db

class Tag(BaseModel):
    name = CharField()

class Path(BaseModel):
    name = CharField()
    tags = ManyToManyField(Tag, backref='path')

PathTags = Path.tags.get_through_model()

db.create_tables([
    Tag,
    Path,
    PathTags])

my_path = ['div', 'div', 'div', 'div', 'div', 'ul', 'li', 'a']

path_id = Path.insert(name='my_path').execute()

path_obj = Path.get(path_id)

for i in my_path:
    path_obj.tags.add(i)

1 Ответ

0 голосов
/ 26 октября 2019

В поле «многие ко многим» предполагается, что два внешних ключа, составляющих отношение, являются уникальными. Если вы посмотрите на исходный код, то увидите, что есть два уникальных ограничения на две fks в таблице. Ваш пример странный, потому что вы говорите не о наборе отношений, а о порядке вещей, которые вы нормализовали в отдельной таблице по какой-то безумной причине (тег). Короче говоря, все это слишком много.

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

Также ваш код неэффективен. Просто сделай:

path_obj = Path.create(name='my_path')
path_obj.tags.add(my_path)
...