def test_reflect(self): # Schema class A1(self.Base): id = Column(Integer, primary_key=True) same = Column(String) class A2(self.Base): id = Column(Integer, primary_key=True) same = Column(String) self.create_all() # Data for source with self.db.begin(): a1 = A1(id=2, same='s1') self.db.add(a1) # Test when reflection doesn't exist with DBHistory(self.db) as hist, self.db.begin(): a2 = replication.reflect(a1, A2) hist.assert_nothing_happened() self.assertIsNone(a2) # Data for target (reflection exists) with self.db.begin(): a2 = A2(id=2, same='s2') self.db.add(a2) # Test when reflection is already loaded with DBHistory(self.db) as hist, self.db.begin(): a2 = replication.reflect(a1, A2) hist.assert_nothing_happened() self.assertIsNotNone(a2) self.assertEqual(a2.same, 's2') # Once more but when reflection is not loaded self.db.expunge(a2) with DBHistory(self.db) as hist, self.db.begin(): a2 = replication.reflect(a1, A2) hist.assert_nothing_happened() self.assertIsNotNone(a2) self.assertEqual(a2.same, 's2')
def test_ordering_list_duplicate_reference(self): # Schema class A1(self.Base): id = Column(Integer, primary_key=True) bs = relationship('B1', order_by='B1.position', cascade='all,delete-orphan', collection_class=ordering_list('position')) class C1(self.Base): id = Column(Integer, primary_key=True) class B1(self.Base): a_id = Column(ForeignKey(A1.id), nullable=False, primary_key=True) position = Column(Integer, nullable=False, primary_key=True) c_id = Column(ForeignKey(C1.id), nullable=False) c = relationship(C1) data = Column(String) class A2(self.Base): id = Column(Integer, primary_key=True) bs = relationship('B2', order_by='B2.position', cascade='all,delete-orphan', collection_class=ordering_list('position')) class C2(self.Base): id = Column(Integer, primary_key=True) class B2(self.Base): a_id = Column(ForeignKey(A2.id), nullable=False, primary_key=True) position = Column(Integer, nullable=False, primary_key=True) c_id = Column(ForeignKey(C2.id), nullable=False) c = relationship(C2) data = Column(String) self.create_all() # Data with self.db.begin(): c1 = C1(id=1) self.db.add(c1) c2 = replication.replicate(c1, C2) with self.db.begin(): a1 = A1(bs=[B1(c=c1, data='a'), B1(c=c1, data='b')]) self.db.add(a1) # Test when reflection doesn't exist with DBHistory(self.db) as hist, self.db.begin(): a2 = replication.replicate(a1, A2) hist.assert_created_one(A2) self.assertEqual(len(a2.bs), 2) self.assertEqual(a2.bs[0].data, 'a') self.assertEqual(a2.bs[1].data, 'b') self.assertIs(a2.bs[0].c, c2) self.assertIs(a2.bs[1].c, c2) # Test when reflection exists with DBHistory(self.db) as hist, self.db.begin(): a1.bs += [B1(c=c1, data='c')] a2 = replication.replicate(a1, A2) hist.assert_created_one(B2) self.assertEqual(len(a2.bs), 3) self.assertEqual(a2.bs[0].data, 'a') self.assertEqual(a2.bs[1].data, 'b') self.assertEqual(a2.bs[2].data, 'c') self.assertIs(a2.bs[0].c, c2) self.assertIs(a2.bs[1].c, c2) self.assertIs(a2.bs[2].c, c2)
def test_replicate_m2m(self): # Schema class AB1(self.Base): a_id = Column(ForeignKey('A1.id'), primary_key=True) b_id = Column(ForeignKey('B1.id'), primary_key=True) class A1(self.Base): id = Column(Integer, primary_key=True) data = Column(String) b = relationship('B1', secondary=AB1.__table__) class B1(self.Base): id = Column(Integer, primary_key=True) a = relationship('A1', secondary=AB1.__table__) class AB2(self.Base): a_id = Column(ForeignKey('A2.id'), primary_key=True) b_id = Column(ForeignKey('B2.id'), primary_key=True) class A2(self.Base): id = Column(Integer, primary_key=True) data = Column(String) b = relationship('B2', secondary=AB2.__table__) class B2(self.Base): id = Column(Integer, primary_key=True) a = relationship('A2', secondary=AB2.__table__) self.create_all() # Data with self.db.begin(): a1 = A1(id=2, data='a1') b1 = B1(id=2, a=[a1]) self.db.add_all([a1, b1]) # Reflections of both objects don't exist with DBHistory(self.db) as hist, self.db.begin(): a2 = replication.replicate(a1, A2) hist.assert_created_one(A2) self.assertEqual(a2.id, a1.id) self.assertEqual(a2.b, []) # Only reflection of replicated object exists with DBHistory(self.db) as hist, self.db.begin(): b2 = replication.replicate(b1, B2) hist.assert_created_one(B2) self.assertEqual(b2.id, b1.id) self.assertEqual(b2.a, [a2]) self.assertEqual(a2.b, [b2]) # Verify that related objects are not updated with self.db.begin(): a1.data = 'a2' b2 = replication.replicate(b1, B2) self.assertEqual(b2.id, b1.id) self.assertEqual(b2.a, [a2]) self.assertEqual(a2.data, 'a1') # Removal with self.db.begin(): a1.b = [] a2 = replication.replicate(a1, A2) self.assertEqual(a2.id, a1.id) self.assertEqual(a2.b, []) self.assertEqual(b2.a, [])
def test_replicate_o2m_private(self): # Schema class P1(self.Base): id = Column(Integer, primary_key=True) children = relationship('C1', cascade='all,delete-orphan') class C1(self.Base): id = Column(Integer, primary_key=True) parent_id = Column(ForeignKey(P1.id), nullable=False) parent = relationship(P1) data = Column(String) class P2(self.Base): id = Column(Integer, primary_key=True) children = relationship('C2', cascade='all,delete-orphan') class C2(self.Base): id = Column(Integer, primary_key=True) parent_id = Column(ForeignKey(P2.id), nullable=False) parent = relationship(P2) data = Column(String) self.create_all() # Data with self.db.begin(): p1 = P1(id=2, children=[C1(id=2, data='a1')]) self.db.add(p1) # New with DBHistory(self.db) as hist, self.db.begin(): p2 = replication.replicate(p1, P2) hist.assert_created_one(P2) hist.assert_created_one(C2) self.assertEqual(len(p2.children), 1) self.assertEqual(p2.children[0].id, 2) self.assertEqual(p2.children[0].data, 'a1') # Append new child and update existing with self.db.begin(): p1.children[0].data = 'a2' p1.children.append(C1(id=4, data='b1')) with DBHistory(self.db) as hist, self.db.begin(): p2 = replication.replicate(p1, P2) hist.assert_created_one(C2) hist.assert_updated_one(C2) self.assertEqual(len(p2.children), 2) self.assertEqual(set([(c.id, c.data) for c in p2.children]), set([(2, 'a2'), (4, 'b1')])) # Update one and remove other child with self.db.begin(): p1.children = [C1(id=4, data='b2')] with DBHistory(self.db) as hist, self.db.begin(): p2 = replication.replicate(p1, P2) self.assertEqual(self.db.query(C2).count(), 1) self.assertEqual(len(p2.children), 1) self.assertEqual(p2.children[0].id, 4) self.assertEqual(p2.children[0].data, 'b2')
def test_replicate_declared_attr(self): # Schema class Common(object): @declared_attr def id(cls): return Column(Integer, primary_key=True) @declared_attr def same(cls): return Column(String) class A1(self.Base, Common): pass class A2(self.Base, Common): pass self.create_all() # Data with self.db.begin(): a1 = A1(id=2, same='s') self.db.add(a1) # Test when reflection doesn't exist with DBHistory(self.db) as hist, self.db.begin(): a2 = replication.replicate(a1, A2) hist.assert_created_one(A2) self.assertIsNotNone(a2) self.assertEqual(a2.id, a1.id) self.assertEqual(a2.same, 's')
def test_models_history_deleted(self): session = self.session user = User(name='test') session.add(user) session.commit() session.expire_all() with DBHistory(session) as history: user = session.query(User).get(user.id) session.delete(user) session.commit() self.assertEqual(history.created_idents, {}) self.assertEqual(history.updated_idents, {}) self.assertEqual(history.deleted_idents, {User: set([(1,)])}) self.assertEqual(history.last_created(User), set()) self.assertEqual(history.last_updated(User), set()) self.assertEqual(history.last_deleted(User), set([(user.id,)])) self.assertRaises(AssertionError, history.assert_created, User) self.assertRaises(AssertionError, history.assert_created_one, User) self.assertRaises(AssertionError, history.assert_updated, User) self.assertRaises(AssertionError, history.assert_updated_one, User) self.assertEqual(history.assert_deleted(User), set([(user.id,)])) self.assertEqual( history.assert_deleted(User, user.id), set([(user.id,)]) ) self.assertEqual(history.assert_deleted_one(User), (user.id,))
def test_nothing_happened_throws_on_creating(self): session = self.session with DBHistory(session) as history: session.add(User(name='test')) session.commit() with self.assertRaises(AssertionError): history.assert_nothing_happened()
def test_replicate_basic(self): # Schema class A1(self.Base): id = Column(Integer, primary_key=True) same = Column(String) different1 = Column(String) class A2(self.Base): id = Column(Integer, primary_key=True) same = Column(String) different2 = Column(String) self.create_all() # Data with self.db.begin(): a1 = A1(id=2, same='s1', different1='d1') self.db.add(a1) # Test when reflection doesn't exist with DBHistory(self.db) as hist, self.db.begin(): a2 = replication.replicate(a1, A2) hist.assert_created_one(A2) self.assertIsNotNone(a2) self.assertEqual(a2.id, a1.id) self.assertEqual(a2.same, 's1') self.assertIsNone(a2.different2) # Update data with self.db.begin(): a1.same = 's2' # Test when reflection is already loaded with DBHistory(self.db) as hist, self.db.begin(): a2 = replication.replicate(a1, A2) hist.assert_updated_one(A2) self.assertIsNotNone(a2) self.assertEqual(a2.id, a1.id) self.assertEqual(a2.same, 's2') self.assertIsNone(a2.different2) # Once more but when reflection is not loaded self.db.expunge(a2) with self.db.begin(): a1.same = 's3' with DBHistory(self.db) as hist, self.db.begin(): a2 = replication.replicate(a1, A2) hist.assert_updated_one(A2) self.assertIsNotNone(a2) self.assertEqual(a2.id, a1.id) self.assertEqual(a2.same, 's3') self.assertIsNone(a2.different2)
def test_models_history_doesnot_use_objects_from_prev_session(self): session = self.session user = User(name='test') user1 = User(name='test1') with DBHistory(session) as history: session.add(user) session.commit() session.add(user1) session.commit()
def test_nothing_happened_throws_on_delete(self): session = self.session user = User(name='test') session.add(user) session.commit() with DBHistory(session) as history: session.delete(user) session.commit() with self.assertRaises(AssertionError): history.assert_nothing_happened()
def test_models_history_init(self): with DBHistory(self.session) as history: self.assertEqual(history.created_idents, {}) self.assertEqual(history.updated_idents, {}) self.assertEqual(history.deleted_idents, {}) self.assertEqual(history.last_created(User), set()) self.assertEqual(history.last_updated(User), set()) self.assertEqual(history.last_deleted(User), set()) self.assertRaises(AssertionError, history.assert_created, User) self.assertRaises(AssertionError, history.assert_updated, User) self.assertRaises(AssertionError, history.assert_deleted, User)
def test_replicate_expression_property(self): # Schema class A1(self.Base): id = Column(Integer, primary_key=True) data = Column(String) expr = column_property(data+' '+data) func = column_property(char_length(data)) class A2(self.Base): id = Column(Integer, primary_key=True) data = Column(String) expr = column_property(data+' '+data) func = column_property(char_length(data)) self.create_all() # Data with self.db.begin(): a1 = A1(id=2, data='aaa') self.db.add(a1) self.assertEqual(a1.expr, 'aaa aaa') self.assertEqual(a1.func, 3) # Test when reflection doesn't exist with DBHistory(self.db) as hist, self.db.begin(): a2 = replication.replicate(a1, A2) hist.assert_created_one(A2) self.assertIsNotNone(a2) self.assertEqual(a2.data, 'aaa') self.assertEqual(a2.expr, 'aaa aaa') self.assertEqual(a2.func, 3) # Update data with self.db.begin(): a1.data = 'aaaaa' # Test when reflection is already loaded with DBHistory(self.db) as hist, self.db.begin(): a2 = replication.replicate(a1, A2) hist.assert_updated_one(A2) self.assertIsNotNone(a2) self.assertEqual(a2.data, 'aaaaa') self.assertEqual(a2.expr, 'aaaaa aaaaa') self.assertEqual(a2.func, 5)
def test_replicate_o2o(self): # Schema class P1(self.Base): id = Column(Integer, primary_key=True) child = relationship('C1', uselist=False) class C1(self.Base): id = Column(Integer, primary_key=True) parent_id = Column(ForeignKey(P1.id), unique=True) parent = relationship(P1) class P2(self.Base): id = Column(Integer, primary_key=True) child = relationship('C2', uselist=False) class C2(self.Base): id = Column(Integer, primary_key=True) parent_id = Column(ForeignKey(P2.id), unique=True) parent = relationship(P2) self.create_all() # Data: reflections for both child and parent don't exist with self.db.begin(): c1 = C1(id=2) p1 = P1(id=2, child=c1) c2 = C2(id=2) self.db.add_all([p1, c2]) # Reflection for one parent exists, property is not reflected for this # direction with DBHistory(self.db) as hist, self.db.begin(): p2 = replication.replicate(p1, P2) hist.assert_created_one(P2) assert len(hist.created_idents)==1 self.assertEqual(p2.id, p1.id) self.assertIsNone(p2.child) # Replication from other side, property is reflected with DBHistory(self.db) as hist, self.db.begin(): c2r = replication.replicate(c1, C2) hist.assert_updated_one(C2) self.assertIs(c2r, c2) self.assertIs(c2.parent, p2)
def test_replicate_o2o_private(self): # Schema class P1(self.Base): id = Column(Integer, primary_key=True) child = relationship('C1', uselist=False, cascade='all,delete-orphan') class C1(self.Base): id = Column(ForeignKey(P1.id), primary_key=True) parent = relationship(P1) data = Column(String) class P2(self.Base): id = Column(Integer, primary_key=True) child = relationship('C2', uselist=False, cascade='all,delete-orphan') class C2(self.Base): id = Column(ForeignKey(P2.id), primary_key=True) parent = relationship(P2) data = Column(String) self.create_all() # Data with self.db.begin(): p1 = P1(id=2, child=C1(data='a1')) self.db.add(p1) # New with DBHistory(self.db) as hist, self.db.begin(): p2 = replication.replicate(p1, P2) hist.assert_created_one(P2) hist.assert_created_one(C2) self.assertIsNotNone(p2.child) # Update child with self.db.begin(): p1.child.data = 'a2' p2 = replication.replicate(p1, P2) self.assertIsNotNone(p2.child) self.assertEqual(p2.child.id, 2) self.assertEqual(p2.child.data, 'a2') # Change child with self.db.begin(): p1.child = C1(data='a3') self.db.flush() # XXX Right now fails without this p2 = replication.replicate(p1, P2) self.assertIsNotNone(p2.child) self.assertEqual(p2.child.id, 2) self.assertEqual(p2.child.data, 'a3') # Remove child (set to None) with self.db.begin(): p1.child = None p2 = replication.replicate(p1, P2) self.assertIsNone(p2.child)
def test_models_history_with_manual_flush_and_rollback(self): session = self.session class SomeException(Exception): pass user = User(name='test') session.add(user) session.commit() try: with DBHistory(session) as history: session.add(User(name='test1')) session.delete(user) session.flush() session.add(User(name='test2')) raise SomeException() except SomeException: pass self.assertFalse(history.created_idents) self.assertFalse(history.updated_idents) self.assertFalse(history.deleted_idents)
def test_models_history_created_with_scoped_session(self): session = self.scoped_session() with DBHistory(session) as history: user = User(name='test') session.add(user) session.commit() self.assertEqual(history.created_idents, {User: set([(1,)])}) self.assertEqual(history.updated_idents, {}) self.assertEqual(history.deleted_idents, {}) self.assertEqual(history.last_created(User), set([user])) self.assertEqual(history.last_updated(User), set()) self.assertEqual(history.last_deleted(User), set()) self.assertEqual(history.assert_created(User), set([user])) self.assertEqual(history.assert_created(User, user.id), set([user])) self.assertEqual(history.assert_created_one(User), user) self.assertRaises(AssertionError, history.assert_updated, User) self.assertRaises(AssertionError, history.assert_updated_one, User) self.assertRaises(AssertionError, history.assert_deleted, User) self.assertRaises(AssertionError, history.assert_deleted_one, User)
def test_exclude_column(self): # Schema class A1(self.Base): id = Column(Integer, primary_key=True) data = Column(String) replication.exclude(data) class A2(self.Base): id = Column(Integer, primary_key=True) data = Column(String) self.create_all() # Data with self.db.begin(): a1 = A1(id=2, data='a') self.db.add(a1) # Test with DBHistory(self.db) as hist, self.db.begin(): a2 = replication.replicate(a1, A2) self.assertIsNotNone(a2) self.assertEqual(a2.id, a1.id) self.assertIsNone(a2.data)
def test_replicate_renamed(self): '''Test replication when name of attribute is not equal to the name of column (but they are the same in both source and target classes, otherwise result is undefined)''' # Schema class A1(self.Base): id = Column(Integer, primary_key=True) name = Column('other_name', String) class A2(self.Base): id = Column(Integer, primary_key=True) name = Column('other_name', String) self.create_all() # Data with self.db.begin(): a1 = A1(id=2, name='n') self.db.add(a1) # Test with DBHistory(self.db) as hist, self.db.begin(): a2 = replication.replicate(a1, A2) hist.assert_created_one(A2) self.assertIsNotNone(a2) self.assertEqual(a2.id, a1.id) self.assertEqual(a2.name, 'n')
def test_nothing_happened_does_not_throw_when_nothing_happened(self): session = self.session with DBHistory(session) as history: session.query(User).all() history.assert_nothing_happened()
def test_replicate_m2o(self): # Schema class P1(self.Base): id = Column(Integer, primary_key=True) class C1(self.Base): id = Column(Integer, primary_key=True) parent_id = Column(ForeignKey(P1.id)) parent = relationship(P1) class P2(self.Base): id = Column(Integer, primary_key=True) class C2(self.Base): id = Column(Integer, primary_key=True) parent_id = Column(ForeignKey(P2.id)) parent = relationship(P2) self.create_all() # Data: reflections for both child and parent don't exist with self.db.begin(): p11 = P1(id=2) c1 = C1(id=2, parent=p11) self.db.add(c1) # Test with DBHistory(self.db) as hist, self.db.begin(): c2 = replication.replicate(c1, C2) hist.assert_created_one(C2) self.assertEqual(len(hist.created_idents), 1) self.assertEqual(c2.id, c1.id) self.assertIsNone(c2.parent) # Reflection for child already exists and loaded self.assertEqual(c1.parent, p11) with DBHistory(self.db) as hist, self.db.begin(): c2 = replication.replicate(c1, C2) self.assertEqual(c2.id, c1.id) self.assertIsNone(c2.parent) # Reflection for child already exists but not loaded self.db.expunge(c2) with DBHistory(self.db) as hist, self.db.begin(): c2 = replication.replicate(c1, C2) self.assertEqual(c2.id, c1.id) self.assertIsNone(c2.parent) # Reflection parent does exist, but not for child with self.db.begin(): self.db.delete(c2) p21 = P2(id=2) self.db.add(p21) with DBHistory(self.db) as hist, self.db.begin(): c2 = replication.replicate(c1, C2) hist.assert_created_one(C2) self.assertEqual(c2.id, c1.id) self.assertEqual(c2.parent, p21) # Reflection for child doesn't exist, but not for parent with self.db.begin(): c1.parent = p12 = P1(id=4) with DBHistory(self.db) as hist, self.db.begin(): c2 = replication.replicate(c1, C2) hist.assert_updated_one(C2) self.assertEqual(c2.id, c1.id) self.assertIsNone(c2.parent) # Replicate when relation is None with self.db.begin(): c1.parent = None c2 = replication.replicate(c1, C2) self.assertIsNone(c2.parent)