Skip to content

Instantly share code, notes, and snippets.

@chadrik
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chadrik/c3fff520bd41a48f0a57 to your computer and use it in GitHub Desktop.
Save chadrik/c3fff520bd41a48f0a57 to your computer and use it in GitHub Desktop.
demo of non-deterministic event ordering
import sqlalchemy
from sqlalchemy import event
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine, Table, Column, Integer, String, ForeignKey
from sqlalchemy.orm import sessionmaker, scoped_session, relationship, backref
import datetime
Base = declarative_base()
engine = create_engine('sqlite://', echo=False)
Session = scoped_session(sessionmaker(bind=engine))
def associate(id1, id2, type1=Integer, type2=Integer):
def get_table(id):
return id.split('.')[0]
def get_id(id):
if '.' not in id:
return id + '.id'
return id
def get_column(id):
return get_table(id) + '_id'
return Table(
'link_%s_%s' % (get_table(id1), get_table(id2)), Base.metadata,
Column(get_column(id1), type1, ForeignKey(get_id(id1))),
Column(get_column(id2), type2, ForeignKey(get_id(id2)))
)
class Author(Base):
__tablename__ = 'author'
# __mapper_args__ = {'batch': False}
id = Column(Integer, primary_key=True)
name = Column(String(80))
email = Column(String)
def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, self.id)
class Book(Base):
__tablename__ = 'book'
# __mapper_args__ = {'batch': False}
id = Column(Integer, primary_key=True)
title = Column(String(80))
year = Column(Integer, nullable=True)
authors = relationship(Author,
secondary=Table(
'link_books_authors', Base.metadata,
Column('book_id', Integer,
ForeignKey('book.id')),
Column('author_id', Integer,
ForeignKey('author.id'))),
backref='books')
def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, self.id)
@event.listens_for(Book, 'after_update')
def book_after_update(mapper, connection, instance):
print "after_update", instance, instance.authors
@event.listens_for(Book, 'after_insert')
def book_after_insert(mapper, connection, instance):
print "after_insert", instance, instance.authors
# @event.listens_for(Author, 'after_update')
# def author_after_update(mapper, connection, instance):
# global book_ran
# print book_ran
# print "author_after_update", instance
@event.listens_for(Author, 'after_insert')
def author_after_insert(mapper, connection, instance):
print "after_insert", instance
def test():
Base.metadata.create_all(engine)
book = Book(title='sqlalchemy for dummies')
session = Session()
session.add(book)
session.commit()
john = Author(name='John Doe')
jane = Author(name='Jane Doe')
book.authors = [john, jane]
book2 = Book(title='sqlalchemy pro tips')
book2.authors = [john]
session.add(book2)
session.commit()
if __name__ == '__main__':
test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment