class TestGetOrCreateAndUpdate(unittest.TestCase): ''' Tests and demonstrates ORM.get_or_create_and_update(self, mapped_class, query_dict, update_dict). get_or_create_and_update(...) tries to retrieve or create a unique mapped_class object identified by attributes in query dict; then tries to update this object with attributes in update_dict; and if successful, returns the object. get_or_create_and_update(...) uses get_or_create(...) and _update_object(...), which raise exceptions when query_dict identifies more than one object, or when invalid attributes are specified. Also tests and demonstrates internal convenience method ORM._update_object(self, obj, **keyword_args). _update_object(...) updates obj's attributes/values corresponding to **keyword_args. It checks each keyword to make sure the object has an attribute of the same name; if not, the exception AttributeError is raised. ''' def setUp(self): orm_defs = dict( Thing = dict( __tablename__ = 'thing', id = Column('id', Integer, primary_key = True), name = Column('name', Text), attribute = Column('attribute', Text), ), ) self.orm = ORM(orm_defs, 'sqlite:///:memory:', deferred_reflection = False) self.thing = self.orm.get_or_create(self.orm.Thing, name="Mary Quite Contrary") def test_update_object(self): self.orm._update_object(self.thing, attribute="Sneakiness") thing2 = self.orm.get_or_create(self.orm.Thing, name="Mary Quite Contrary") self.assertEqual(thing2.attribute, "Sneakiness") def test_nonsense_update_raises(self): # Verify AttributeError is raised upon update of nonsense attribute. with self.assertRaises(AttributeError): self.orm._update_object(self.Thing, nonsense_attribute="Blue") # Nearby negative control self.orm._update_object(self.thing, attribute="Deceptive") def test_get_or_create_and_update(self): query_dict = dict(name="Rumplestiltskin") update_dict_1 = dict(attribute="Sneakiness") update_dict_2 = dict(attribute="Meanness") # Run get_or_create_and_update(...) twice, with identical query dict to # uniquely determine object, but with two different update dicts. thing_1 = self.orm.get_or_create_and_update(self.orm.Thing, query_dict, update_dict_1) self.assertEqual(thing_1.attribute, "Sneakiness") thing_2 = self.orm.get_or_create_and_update(self.orm.Thing, query_dict, update_dict_2) # After second call, attribute should have changed, but thing1 and # thing2 should still be the unique object identified by name # "Rumplestiltskin. self.assertEqual(thing_1.attribute, "Meanness") self.assertEqual(thing_1, thing_2)
class TestGetOrCreateUniqueObject(unittest.TestCase): ''' Tests and demonstrates ORM.get_or_create(self, mapped_class, **keyword_args). get_or_create(...) tries to retrieve and return a single object of type mapped_class, uniquely identified by **keyword_args. If no such object can be found, one will be created. If **keyword_args identify multiple objects, the exception sqlalchemy.orm.exc.MultipleResultsFound is raised. ''' def setUp(self): orm_defs = dict( Thing = dict( __tablename__ = 'thing', id = Column('id', Integer, primary_key = True), name = Column('name', Text), ), ) self.orm = ORM(orm_defs, 'sqlite:///:memory:', deferred_reflection = False) def test_create_unique(self): # Create a unique Thing object identified by name "Rumplestiltskin". self.assertEqual(0, self.orm.session.query(self.orm.Thing).count()) thing1 = self.orm.get_or_create(self.orm.Thing, name="Rumplestiltskin") self.assertEqual(1, self.orm.session.query(self.orm.Thing).count()) # Retrieve the Thing object uniquely identified by name "Rumplestiltskin". thing2 = self.orm.get_or_create(self.orm.Thing, name="Rumplestiltskin") self.assertEqual(1, self.orm.session.query(self.orm.Thing).count()) # Verify that the created and the retrieved objects are the same thing. self.assertEqual(thing1, thing2) def test_error_on_nonunique(self): # Create a unique Thing object identified by name "Rumplestiltskin. self.assertEqual(0, self.orm.session.query(self.orm.Thing).count()) thing1 = self.orm.get_or_create(self.orm.Thing, name="Rumplestiltskin") self.assertEqual(1, self.orm.session.query(self.orm.Thing).count()) # Create a second Thing object identified by the same name. thing2 = self.orm.Thing(name="Rumplestiltskin") self.orm.session.add(thing2) self.orm.session.commit() # Since things are no longer uniquely identified by name # "Rumplestiltskin", get_or_create(...) should fail if we try to # uniquly identify a thing by name "Rumplestiltskin. with self.assertRaises(MultipleResultsFound): self.orm.get_or_create(self.orm.Thing, name="Rumplestiltskin") def test_attribute_error(self): # Can't uniquely identify a Thing object with nonsense attributes. with self.assertRaises(AttributeError): thing1 = self.orm.get_or_create(self.orm.Thing, nonsense_attribute="Color of the sky") # Nearby negative control thing1 = self.orm.get_or_create(self.orm.Thing, name="Rumplestiltskin")