Вам действительно нужно оптимизировать его для большой нагрузки?Вероятно, нет, если вы используете SQLite.Простое решение в этом случае намного лучше:
class Like(Base):
__tablename__ = 'Like'
id = Column(Integer, primary_key=True)
counter = Column(Integer, nullable=False, default=0)
o = session.merge(Like(id=1))
session.flush() # Required when it's new record
o.counter = Like.counter+1
session.commit()
Между проверкой и вставкой существует условие гонки, но я считаю, что на практике это вас не побьет.
Когда вы действительнонужно немного его оптимизировать или исправить это состояние гонки, в SQLite есть INSERT OR IGNORE
, чтобы избежать проверки (еще выполняется 2 отдельных оператора):
clause = Like.__table__.insert(prefixes=['OR IGNORE'],
values=dict(id=1, counter=0))
session.execute(clause)
o = session.merge(Like(id=1, counter=Like.counter+1))
session.commit()
И, наконец, есть способсделайте это в одном выражении, используя INSERT OR REPLACE
и вложенный выбор (есть другие способы сделать это в большинстве других баз данных, например, ON DUPLICATE KEY
в MySQL), но я сомневаюсь, что это даст вам заметный прирост производительности:
old = session.query(Like.counter).filter_by(id=1).statement.as_scalar()
new = func.ifnull(old, 0) + 1
clause = Like.__table__.insert(prefixes=['OR REPLACE'],
values=dict(id=1, counter=new))
session.execute(clause)