Многие-ко-многим в sqlalchemy. Предотвращение вставки SQLAlchemy в таблицу, если тег уже существует

У меня есть несколько таблиц с сопоставлением ORM, которые (уменьшены) выглядят следующим образом:

class Tag(Base): __tablename__ = 'tags' tag_name = Column(String, primary_key=True) task2tag_assoc = Table('tasktags', Base.metadata, Column('task_id', UUID, ForeignKey('tasks.task_id', ondelete='cascade'), primary_key=True), Column('tag_name', String, ForeignKey('tags.tag_name', ondelete='cascade'), primary_key=True) ) class Task(Base): __tablename__ = 'tasks' task_id = Column(UUID, primary_key=True) _tags = relationship('Tag', secondary=task2tag_assoc, backref='tasks', collection_class=set) tags = association_proxy('_tags', 'tag_name') def __init__(self, task_id, tags): self.task_id = task_id self.tags = set([tags]) 

С помощью этой настройки я могу создать задачу с новыми тегами. Он создает строку тега в таблице tags , а затем создает связь с новой задачей, просто отлично в таблице tasktags .

 t = Task(task_id = uuid4(), tags=['foo', 'bar']) #this works 

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

 t2 = Task(task_oid = uuid4(), tags=['foo', 'baz']) #this will give an integrity error 

Кажется, SQLAlchemy всегда пытается вставить тег в таблицу тэгов, независимо от того, существует ли она уже. Мне бы очень хотелось создать ассоциацию только в том случае, если тег уже существует. Похоже, это было бы довольно нормально во многих ситуациях, но я не могу найти нигде в документации, показывающей, что я могу делать неправильно.

Есть ли способ получить поведение, которое я хочу?

Для фона я использую postgresql 9.1 DB с драйвером psycopg2, а SQLAlchemy 0.7.9 (Python 2.7.3)

Вещи, которые я рассматриваю как последнее средство: теги технически являются первичным ключом, и больше ничего, я мог бы избежать просто таблицы тегов task_id-> и таблицы тегов. Но я хотел бы иметь возможность прикреплять метаданные к самим тегам по дороге, если это становится необходимым.

2 Solutions collect form web for “Многие-ко-многим в sqlalchemy. Предотвращение вставки SQLAlchemy в таблицу, если тег уже существует”

для рецепта «только уникальные теги» Я обычно использую уникальный рецепт объекта или его вариант: http://www.sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObject .

Для этого, естественно, требуется SELECT для определенной строки, чтобы определить, существует ли она в первую очередь. Метод «upsert», используя команды, специфичные для базы данных, для INSERT или UPDATE, на основе определения на стороне базы данных напрямую не поддерживается ORM прямо сейчас. Вы все равно на Postgresql, который фактически не поддерживает какую-либо собственную функцию «upsert», кроме одной очень неудобной системы, использующей общие табличные выражения.

Попробуйте удалить связанные ссылки, такие как t2._tags = []

 t2 = Task(task_oid = uuid4()) t2._tags = [] tags = ['foo', 'baz'] for tag in tags: t2._tags.append(Tag(tag)) 
  • SQLAlchemy: Любое ограничение для проверки одного из двух столбцов не является нулевым?
  • Создайте динамическую форму, используя флягу-wtf и sqlalchemy
  • хранимые процедуры с sqlAlchemy
  • Flask-SQLAlchemy: не удается повторно подключиться до отмены отката транзакции
  • Как сделать соединение mysql, требующее CA-CERT с sqlalchemy или SQLObject
  • sqlalchemy: как присоединиться к нескольким таблицам по одному запросу?
  • Результат SQLAlchemy для столбца UTF-8 имеет тип 'str', почему?
  • Возможно ли заполнить внешний ключ SQLalchemy в модели и загрузить его связанный объект
  •  
    Interesting Posts for Van-Lav

    Как incr работает со временем истечения срока действия?

    Почему Django использует кортежи для настроек, а не для списков?

    Создание фигур или букв с помощью Python

    Шаблоны Django: переопределение блоков включенных шаблонов для детей через расширенный шаблон

    Возвращение отдельных строк в SQLAlchemy с помощью SQLite

    Как напечатать возвращаемое значение метода в Python?

    Обработка subprocess.call () в Django

    Как я могу использовать valgrind с расширениями Python C ++?

    Реализация итератора в Julia для анимации с PyPlot

    Запись изображения pandas / matplotlib непосредственно в файл XLSX

    Является ли MATLAB быстрее, чем Python?

    Использование WordNet для определения семантического сходства между двумя текстами?

    Pandas: как передать имя столбца функции, которая затем может использоваться в 'apply'?

    Байесовская библиотека фильтрации спама для Python

    сортировать значения и возвращать список ключей из dict python

    Python - лучший язык программирования в мире.