Hi, I'm running into a problem illustrated by the code below. The result is an IntegrityError:
sqlalchemy.exc.IntegrityError: (IntegrityError) null value in column "group_id" violates not-null constraint 'INSERT INTO groups_owners (owner_id, item_id) VALUES (%(owner_id)s, % (item_id)s) RETURNING groups_owners.group_id' {'item_id': 1, 'owner_id': 1} Looking at the stack trace, autoflush is triggerred by the assignments in GroupOwner.__init__(), but I fail to see why or what to do about it. The error appeared when I set a backref with uselist=False on the GroupOwner.item relationship. I can work around the problem by using a list instead, although that would make less sense since there's at most one group per item. Is there an error in my relationship configuration? I'm running SA 0.6.6. ==== Code to reproduce the error ==== from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.orm.collections import attribute_mapped_collection from sqlalchemy import Table, Column, Integer, Numeric, String, ForeignKey, MetaData from sqlalchemy.engine import create_engine from sqlalchemy.orm import sessionmaker, mapper, relationship, backref meta = MetaData() engine = create_engine('postgresql://test:test@localhost/test') Session = sessionmaker(bind=engine) session = Session() owners = Table("owners", meta, Column('id', Integer, primary_key=True), Column('name', String) ) items = Table("items", meta, Column('id', Integer, primary_key=True), Column('name', String), Column('owner_id', Integer, ForeignKey('owners.id')) ) groups = Table("groups", meta, Column('id', Integer,primary_key=True), ) groups_owners = Table("groups_owners", meta, Column('group_id', Integer, ForeignKey('groups.id'), primary_key=True), Column('owner_id', Integer, ForeignKey('owners.id'), primary_key=True), Column('item_id', Integer, ForeignKey('items.id'), nullable=False, unique=True) # notice unique=True; items can belong to one group at most ) def _create_holding(stock, shares): """A creator function, constructs Holdings from Stock and share quantity.""" return Holding(stock=stock, shares=shares) class Owner(object): def __init__(self, name): self.name = name holdings = association_proxy('by_stock', 'shares', creator=_create_holding) class Item(object): def __init__(self, name, owner): self.name = name self.owner = owner class GroupOwner(object): def __init__(self, group, owner, item): self.group = group self.owner = owner self.item = item #assert item.owner is owner @classmethod def create_for_proxy(cls, owner, item): return cls(None, owner, item) class Group(object): def __init__(self, items): if items: for item in items: self.items_by_owner[item.owner] = item items_by_owner = association_proxy('group_owners', 'item', creator=GroupOwner.create_for_proxy) mapper(Owner, owners) mapper(Item, items, properties={ 'owner': relationship(Owner), }) mapper(Group, groups, properties={ 'group_owners': relationship(GroupOwner, collection_class=attribute_mapped_collection('owner')), }) mapper(GroupOwner, groups_owners, properties={ 'group': relationship(Group), # Fails 'item': relationship(Item, backref=backref('group_owners', uselist=False), single_parent=True), # Doesn't fail #'item': relationship(Item, backref=backref('group_owners'), single_parent=True), 'owner': relationship(Owner), }) meta.drop_all(bind=engine, checkfirst=True) meta.create_all(bind=engine) owner1 = Owner('owner 1') item1 = Item('item 1', owner1) owner2 = Owner('owner 2') item2 = Item('item 2', owner2) session.add(owner1) session.add(owner2) session.add(item1) session.add(item2) session.flush() # Fails: group = Group([item1, item2]) # Doesn't fail #group = Group([item1]) session.add(group) session.commit() assert session.query(GroupOwner).filter_by(group_id=1, item_id=1, owner_id=1).first() is not None print 'Done.' -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.