Issues

Issue #3016 invalid

Ordered list is not correctly ordered on setattr

Marc Schlaich
created an issue

I have a case where I build a new collection based on some existing elements from the old collection and adding new ones. On setattr the new collections, some elements have already set the order by attribute and some of them not. Here is the issue: only the elements with no order by attribute get a value so after a new query the ordering of the list is wrong.

Test case:

from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.orderinglist import ordering_list

Base = declarative_base()


class Slide(Base):
    __tablename__ = 'slide'

    id = Column(Integer, primary_key=True)
    name = Column(String)

    bullets = relationship("Bullet", order_by="Bullet.position",
                           collection_class=ordering_list('position'))


class Bullet(Base):
    __tablename__ = 'bullet'
    id = Column(Integer, primary_key=True)
    slide_id = Column(Integer, ForeignKey('slide.id'))
    position = Column(Integer)
    text = Column(String)


engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)


def test_ordered_list_setattr():
    session = Session()
    s = Slide()
    s.bullets.append(Bullet(text='a'))
    s.bullets.append(Bullet(text='b'))
    session.add(s)
    session.commit()

    s = session.query(Slide).one()
    bullets = list()
    old_bullets = s.bullets[:]
    bullets.append(Bullet(text='c'))
    bullets.extend(old_bullets)
    print [b.position for b in bullets]
    s.bullets = bullets
    session.commit()
    print [b.position for b in bullets]

    s = session.query(Slide).one()
    assert [b.text for b in s.bullets] == ['c', 'a', 'b']

Test run:

$ py.test sqla.py
============================= test session starts =============================
platform win32 -- Python 2.7.6 -- py-1.4.20 -- pytest-2.5.2
collected 1 items

sqla.py F

================================== FAILURES ===================================
__________________________ test_ordered_list_setattr __________________________

    def test_ordered_list_setattr():
        session = Session()
        s = Slide()
        s.bullets.append(Bullet(text='a'))
        s.bullets.append(Bullet(text='b'))
        session.add(s)
        session.commit()

        s = session.query(Slide).one()
        bullets = list()
        old_bullets = s.bullets[:]
        bullets.append(Bullet(text='c'))
        bullets.extend(old_bullets)
        print [b.position for b in bullets]
        s.bullets = bullets
        session.commit()
        print [b.position for b in bullets]

        s = session.query(Slide).one()
>       assert [b.text for b in s.bullets] == ['c', 'a', 'b']
E       assert ['a', 'c', 'b'] == ['c', 'a', 'b']
E         At index 0 diff: u'a' != 'c'

sqla.py:54: AssertionError
------------------------------- Captured stdout -------------------------------
[None, 0, 1]
[0, 0, 1]
========================== 1 failed in 0.27 seconds ===========================

Comments (7)

  1. Log in to comment