Предполагая следующие модели SQL Alchemy:
likes = db.Table('likes',
db.Column('from_id', db.Integer, db.ForeignKey('user.id'), primary_key=True),
db.Column('to_id', db.Integer, db.ForeignKey('user.id'), primary_key=True)
)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
liked_by = db.relationship('User', secondary=likes, foreign_keys=likes.c.to_id, lazy='subquery')
likes = db.relationship('User', secondary=likes, foreign_keys=likes.c.from_id, lazy='subquery')
Что самое быстрый и простой способ добавить много, like
отношений между многими User
объектами таким образом, что не потерпит неудачу, если дубли попытки?
Мое самое близкое решение:
x = [
{'from_id': 1, 'to_id': 2},
{'from_id': 2, 'to_id': 3},
{'from_id': 1, 'to_id': 3},
...
]
stmt = likes.insert().values(x)
session.execute(stmt)
session.commit()
Но вся эта транзакция завершится неудачей, если, например, 1 → 2
уже существует. Есть ли способ выполнить этот оператор таким образом, который добавит новые строки в таблицу likes
и не будет терпеть неудачу в существующих строках?
Решение должно быть выполнено (т.е. Поддерживать массовую вставку). База данных - PostgreSQL 10.x, если требуется не общий ответ.
Вы можете использовать функции "upsert", добавленные в Postgresql несколько недавно. Если вы просто хотите игнорировать дубликаты, используйте ON CONFLICT DO NOTHING:
from sqlalchemy.dialects.postgresql import insert
stmt = insert(likes).values(x).on_conflict_do_nothing()
...