Во-первых, пример кода:Изменение родственный значение объекта автоматически на основании идентификатора от фиксации в SQLAlchemy
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy import event
Base = declarative_base()
class Foo(Base):
__tablename__ = 'foo'
id = Column(Integer, primary_key=True)
label = Column(String)
class Bar(Base):
__tablename__ = 'bar'
id = Column(Integer, primary_key=True)
foo_id = Column(Integer, ForeignKey('foo.id'))
foo = relationship(Foo)
def __init__(self, foo=None):
self.foo = foo if foo else Foo()
print 'init', self.id, self, self.foo.id, self.foo
def _adjust_label(target, value, old_value, initiator):
print 'adjust', target, value, old_value, initiator
if value and not target.foo.label:
target.foo.label = 'autostring %d' % value
print 'adjust', target.id, target, target.foo.id, target.foo, target.foo.label
event.listen(Bar.id, 'set', _adjust_label)
engine = create_engine('sqlite:////path/to/some.db')
Base.metadata.create_all(engine)
session = sessionmaker(bind=engine)()
bar = Bar()
print 'pre-add', bar.id, bar, bar.foo.id, bar.foo
session.add(bar)
print 'added', bar.id, bar, bar.foo.id, bar.foo
session.commit()
print 'commited', bar.id, bar, bar.foo.id, bar.foo, bar.foo.label
Что я получаю:
pre-add None <__main__.Bar object at 0x2929f50>
pre-add None <__main__.Foo object at 0x292e310>
added None <__main__.Bar object at 0x2929f50>
added None <__main__.Foo object at 0x292e310>
adjust <__main__.Bar object at 0x2929f50> 14 None Bar.id
adjust None <__main__.Bar object at 0x2929f50>
adjust 14 <__main__.Foo object at 0x292e310> autostring 14
commited 14 <__main__.Bar object at 0x2929f50>
commited 14 <__main__.Foo object at 0x2932e10> None
Что меня удивляет, что в committed
, bar.foo
является по-разному, чем до фиксации, и что, по-видимому, в результате мое успешное изменение на bar.foo.label
в прослушивателе событий выбрасывается из окна. Я пытаюсь сделать это, потому что мне нужна автоматически созданная уникальная строка для bar.foo.label
, и мне нужно что-то с чуть большим значением, чем чистая случайная строка. Возможно ли это сделать автоматически, с прослушивателем событий или без него, или мне нужно обрабатывать это на более высоком уровне, чем модели ORM?
Отличное решение. Это не произошло со мной. – javex