Module sfx.sfx_main:171 in register_project << raise p = super(SFXProjectRegistrationProvider, self).register_project( neighborhood, shortname, project_name, user, user_project, private_project) p.set_tool_data('sfx', unix_group_name=ug_name) self.api.read(p) >> neighborhood, shortname, project_name, user, user_project, private_project) Module allura.lib.plugin:349 in register_project << users=[user], is_user_project=user_project, is_private_project=private_project) except forge_exc.ProjectConflict: raise >> is_private_project=private_project) Module allura.model.project:578 in configure_project << self.database_configured = True self.notifications_disabled = False ThreadLocalORMSession.flush_all() def add_user(self, user, role_names): >> ThreadLocalORMSession.flush_all() Module ming.orm.ormsession:191 in flush_all << def flush_all(cls): for sess in cls._session_registry.itervalues(): sess.flush() @classmethod >> sess.flush() Module allura.lib.stats:57 in inner << return func(*l, **kw) with stats.timing(self.timer): return func(*l, **kw) inner.__name__ = func.__name__ return inner >> return func(*l, **kw) Module ming.orm.ormsession:25 in inner << def inner(session, *args, **kwargs): before(session, *args, **kwargs) result = func(session, *args, **kwargs) after(session, *args, **kwargs) return result >> result = func(session, *args, **kwargs) Module ming.orm.ormsession:70 in flush << if self.impl.db is None: return if obj is None: self.uow.flush() else: st = state(obj) >> self.uow.flush() Module ming.orm.unit_of_work:41 in flush << st = state(obj) if st.status == ObjectState.new: inow(obj, st) st.status = ObjectState.clean new_objs[i] = obj >> inow(obj, st) Module ming.orm.ormsession:25 in inner << def inner(session, *args, **kwargs): before(session, *args, **kwargs) result = func(session, *args, **kwargs) after(session, *args, **kwargs) return result >> result = func(session, *args, **kwargs) Module ming.orm.ormsession:82 in insert_now << @with_hooks('insert') def insert_now(self, obj, st, **kwargs): mapper(obj).insert(obj, st, **kwargs) @with_hooks('update') >> mapper(obj).insert(obj, st, **kwargs) Module ming.orm.mapper:48 in insert << def insert(self, obj, state, **kwargs): state.document.m.insert(validate=False) self.session.save(obj) state.status = state.clean >> state.document.m.insert(validate=False) Module ming.metadata:123 in inner << curried_args = [ getattr(self, argname) for argname in proxy_args ] all_args = tuple(curried_args) + args return method(*all_args, **kwargs) inner.__name__ = name return inner >> return method(*all_args, **kwargs) Module ming.session:21 in wrapper << def wrapper(self, doc, *args, **kwargs): try: return func(self, doc, *args, **kwargs) except pymongo.errors.OperationFailure, opf: opf.args = opf.args + (('doc: ' + str(doc)),) >> return func(self, doc, *args, **kwargs) Module ming.session:140 in insert << def insert(self, doc, **kwargs): data = self._prep_save(doc, kwargs.pop('validate', True)) bson = self._impl(doc).insert(data, safe=kwargs.get('safe', True)) if bson and '_id' not in doc: doc._id = bson >> bson = self._impl(doc).insert(data, safe=kwargs.get('safe', True)) Module pymongo.collection:275 in insert << self.__database.connection._send_message( message.insert(self.__full_name, docs, check_keys, safe, kwargs), safe) ids = [doc.get("_id", None) for doc in docs] >> check_keys, safe, kwargs), safe) Module pymongo.connection:770 in _send_message << response = self.__receive_message_on_socket(1, request_id, sock) return self.__check_response_to_last_error(response) return None except (ConnectionFailure, socket.error), e: >> return self.__check_response_to_last_error(response) Module pymongo.connection:718 in __check_response_to_last_error << if "code" in error: if error["code"] in [11000, 11001, 12582]: raise DuplicateKeyError(error["err"]) else: raise OperationFailure(error["err"], error["code"]) >> raise DuplicateKeyError(error["err"]) DuplicateKeyError: (u'E11000 duplicate key error index: pyforge.user.$username_1 dup key: { : "niallr" }', "doc: {'username': u'niallr', 'tool_preferences': {}, '_id': ObjectId('4e1ff0d2b9363c1a3e0003b9'), 'tool_data': {'sfx': {'userid': 3471841}}, 'preferences': {'results_per_page': None, 'email_format': None, 'email_address': None}, 'open_ids': [], 'display_name': u'Niall', 'password': None, 'email_addresses': []}")
I can't figure this out - punting to Rick.
forge and forge-classic: rc/2462
I believe this happens because sfx_api's upsert_user method doesn't actually upsert. So I made it upsert. QA is code review and setting it to validation so we can verify it's fixed in prod.
Merged to dev.