#!/usr/bin/env python3 from sqlalchemy import create_engine, String, update, bindparam, case from sqlalchemy.orm import ( DeclarativeBase, Mapped, mapped_column, sessionmaker, scoped_session, ) from typing import Generator from contextlib import contextmanager db_url = "sqlite:////tmp/rhys.db" class Base(DeclarativeBase): pass class Rhys(Base): __tablename__ = "rhys" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) ref_number: Mapped[int] = mapped_column() name: Mapped[str] = mapped_column(String(256), index=True) def __init__(self, session, ref_number: int, name: str) -> None: self.ref_number = ref_number self.name = name session.add(self) session.flush() @contextmanager def Session() -> Generator[scoped_session, None, None]: Session = scoped_session(sessionmaker(bind=engine)) yield Session Session.commit() Session.close() engine = create_engine(db_url) Base.metadata.create_all(engine) inital_number_of_records = 10 def move_rows(session): new_row = 6 with Session() as session: # new_record = Rhys(session, new_row, f"new {new_row=}") # Move rows stmt = ( update(Rhys) .where(Rhys.ref_number > new_row) # .where(Rhys.id.in_(session.query(Rhys.id).order_by(Rhys.id.desc()))) .values({Rhys.ref_number: Rhys.ref_number + 1}) ) session.execute(stmt) sqla_map = [] for k, v in zip(range(11), [0, 1, 2, 3, 4, 7, 8, 10, 5, 6, 9]): sqla_map.append({"oldrow": k, "newrow": v}) # for a, b in sqla_map.items(): # print(f"{a} > {b}") with Session() as session: for a in range(inital_number_of_records): _ = Rhys(session, a, f"record: {a}") stmt = update(Rhys).values( ref_number=case( {item['oldrow']: item['newrow'] for item in sqla_map}, value=Rhys.ref_number ) ) session.connection().execute(stmt, sqla_map)