Example #1
0
 def testCaseLookupTypeCheck(self):
     case = CommCareCase(domain=self.domain, type='nonmatch-type')
     case.save()
     self.assertEqual(1, len(get_case_ids_in_domain(self.domain)))
     config = self._config(self.default_headers)
     file = MockExcelFile(header_columns=self.default_headers, num_rows=3,
                          row_generator=id_match_generator(case._id))
     res = do_import(file, config, self.domain)
     # because the type is wrong these shouldn't match
     self.assertEqual(3, res['created_count'])
     self.assertEqual(0, res['match_count'])
     self.assertEqual(4, len(get_case_ids_in_domain(self.domain)))
    def handle(self, *args, **options):
        with open('bihar_case_cleanup.csv', 'wb') as f:
            csv_file = csv.writer(f)
            csv_file.writerow(CaseRow.headers)

            blank_case_ids = get_case_ids_in_domain('care-bihar',
                                                    type=('', None))
            task_case_ids = get_case_ids_in_domain('care-bihar', type='task')

            case_ids = set(blank_case_ids) | set(task_case_ids)
            to_save = []

            logger.info("Total cases to process: {}".format(len(case_ids)))
            for i, doc in enumerate(iter_docs(CommCareCase.get_db(), case_ids)):
                case = CommCareCase.wrap(doc)

                if case.type and case.type != "task":
                    continue
    
                parent = None
                if case.indices:
                    parent_id = case.indices[0].referenced_id
                    try:
                        parent = CommCareCase.get(parent_id)
                    except ResourceNotFound:
                        parent = MissingParent(get_id=parent_id, owner_id='Parent Missing')

                case_row = CaseRow(case, parent)

                if case.type != 'task':
                    if case.user_id == MOTECH_ID:
                        case_row.update_type('task')

                if parent and not isinstance(parent, MissingParent) and parent.owner_id != case.owner_id:
                    case_row.update_owner(parent.owner_id)

                if case_row.save:
                    csv_file.writerow(case_row.to_row())
                    to_save.append(case_row.case)

                if len(to_save) > 100:
                    CommCareCase.get_db().bulk_save(to_save)
                    to_save = []

                if i % 100 == 0:
                    logger.info("{current}/{count} cases completed".format(current=i, count=len(case_ids)))

            if to_save:
                CommCareCase.get_db().bulk_save(to_save)
 def _get_cases(self):
     case_ids = get_case_ids_in_domain(self.domain)
     return CommCareCase.view(
         '_all_docs',
         keys=case_ids,
         include_docs=True,
     )
    def update_indicators_for_case_type(self, case_type, domain):
        print "\n\n\nFetching %s cases in domain %s...." % (case_type, domain)
        relevant_indicators = CaseIndicatorDefinition.get_all(
            namespace=MVP.NAMESPACE, domain=domain, case_type=case_type
        )

        if relevant_indicators:
            num_cases = get_number_of_cases_in_domain(domain, type=case_type)

            print ("\nFound the following Case Indicator Definitions " "for Case Type %s in Domain %s") % (
                case_type,
                domain,
            )
            print "--%s\n" % "\n--".join([i.slug for i in relevant_indicators])

            print "Found %d possible cases for update." % num_cases
            case_ids = get_case_ids_in_domain(domain, type=case_type)

            self._throttle_updates(
                "Cases of type %s in %s" % (case_type, domain),
                relevant_indicators,
                num_cases,
                domain,
                case_ids,
                CommCareCase,
            )
Example #5
0
 def testImportNamedColumns(self):
     config = self._config(self.default_headers, named_columns=True)
     file = MockExcelFile(header_columns=self.default_headers, num_rows=5)
     res = do_import(file, config, self.domain)
     # we create 1 less since we knock off the header column
     self.assertEqual(4, res['created_count'])
     self.assertEqual(4, len(get_case_ids_in_domain(self.domain)))
    def handle_one(self, domain, case_type, chunk_size):
        self.log('Copying {case_type} cases in {domain}'
                 .format(case_type=case_type, domain=domain))
        old_db = CommCareCase.get_db()
        new_db = IndicatorCase.get_db()
        assert old_db.uri != new_db.uri
        # this dbaccessor pulls from old_db
        case_ids = get_case_ids_in_domain(domain, case_type)
        self.delete_bad_doc_types(case_ids, chunk_size)
        case_dict_chunks = chunked(iter_docs(old_db, case_ids, chunk_size),
                                   chunk_size)

        for case_dicts in case_dict_chunks:
            for case_dict in case_dicts:
                del case_dict['_rev']
                case_dict.pop('_attachments', None)
                case_dict['doc_type'] = "IndicatorCase"
            try:
                results = new_db.bulk_save(case_dicts)
            except BulkSaveError as error:
                results = error.results
            for result in results:
                if result.get('error') == 'conflict':
                    self.log('- OK: [{id}] is already in the indicator db'
                             .format(id=result.get('id')))
                elif 'error' in result:
                    self.log('- ERROR: [{id}] ({result})'.format(
                        id=result.get('id'),
                        result=json.dumps(result)
                    ))
                else:
                    self.log('- ADDED: [{id}] saved to indicator db'.format(
                        id=result.get('id')
                    ))
Example #7
0
 def testImportNone(self, update_state):
     res = bulk_import_async.delay(self._config(['anything']), self.domain, None)
     self.assertIsInstance(res.result, Ignore)
     update_state.assert_called_with(
         state=states.FAILURE,
         meta={'errors': 'Sorry, your session has expired. Please start over and try again.'})
     self.assertEqual(0, len(get_case_ids_in_domain(self.domain)))
Example #8
0
 def testBasicChunking(self):
     config = self._config(self.default_headers)
     file = MockExcelFile(header_columns=self.default_headers, num_rows=5)
     res = do_import(file, config, self.domain, chunksize=2)
     # 5 cases in chunks of 2 = 3 chunks
     self.assertEqual(3, res['num_chunks'])
     self.assertEqual(5, res['created_count'])
     self.assertEqual(5, len(get_case_ids_in_domain(self.domain)))
Example #9
0
    def testNoCreateNew(self):
        config = self._config(self.default_headers, create_new_cases=False)
        file = MockExcelFile(header_columns=self.default_headers, num_rows=5)
        res = do_import(file, config, self.domain)

        # no matching and no create new set - should do nothing
        self.assertEqual(0, res['created_count'])
        self.assertEqual(0, res['match_count'])
        self.assertEqual(0, len(get_case_ids_in_domain(self.domain)))
Example #10
0
    def testExternalIdMatching(self):
        # bootstrap a stub case
        case = CommCareCase(domain=self.domain, type=self.default_case_type)
        external_id = 'importer-test-external-id'
        case.external_id = external_id
        case.save()
        self.assertEqual(1, len(get_case_ids_in_domain(self.domain)))

        headers = ['external_id', 'age', 'sex', 'location']
        config = self._config(headers, search_field='external_id')
        file = MockExcelFile(header_columns=headers, num_rows=3,
                             row_generator=id_match_generator(external_id))
        res = do_import(file, config, self.domain)
        self.assertEqual(0, res['created_count'])
        self.assertEqual(3, res['match_count'])
        self.assertFalse(res['errors'])

        # shouldn't create any more cases, just the one
        self.assertEqual(1, len(get_case_ids_in_domain(self.domain)))
Example #11
0
def update_schedule_case_properties():
    """
    Iterate through all pact patient cases in the domain and set schedule case properties if necessary.
    """
    case_ids = get_case_ids_in_domain("pact", "cc_path_client")
    # this is intentionally not user iter_docs since pact cases are *huge* and we want to use
    # get_lite and only load one at a time.
    for case_id in case_ids:
        case = PactPatientCase.get_lite(case_id)
        set_schedule_case_properties(case)
    def print_stats(self, domain, short=True, diffs_only=False):
        status = get_couch_sql_migration_status(domain)
        print("Couch to SQL migration status for {}: {}".format(domain, status))
        db = get_diff_db(domain)
        try:
            diff_stats = db.get_diff_stats()
        except OperationalError:
            diff_stats = {}

        has_diffs = False
        for doc_type in doc_types():
            form_ids_in_couch = set(get_form_ids_by_type(domain, doc_type))
            form_ids_in_sql = set(FormAccessorSQL.get_form_ids_in_domain_by_type(domain, doc_type))
            diff_count, num_docs_with_diffs = diff_stats.pop(doc_type, (0, 0))
            has_diffs |= self._print_status(
                doc_type, form_ids_in_couch, form_ids_in_sql, diff_count, num_docs_with_diffs, short, diffs_only
            )

        form_ids_in_couch = set(get_doc_ids_in_domain_by_type(
            domain, "XFormInstance-Deleted", XFormInstance.get_db())
        )
        form_ids_in_sql = set(FormAccessorSQL.get_deleted_form_ids_in_domain(domain))
        diff_count, num_docs_with_diffs = diff_stats.pop("XFormInstance-Deleted", (0, 0))
        has_diffs |= self._print_status(
            "XFormInstance-Deleted", form_ids_in_couch, form_ids_in_sql,
            diff_count, num_docs_with_diffs, short, diffs_only
        )

        case_ids_in_couch = set(get_case_ids_in_domain(domain))
        case_ids_in_sql = set(CaseAccessorSQL.get_case_ids_in_domain(domain))
        diff_count, num_docs_with_diffs = diff_stats.pop("CommCareCase", (0, 0))
        has_diffs |= self._print_status(
            'CommCareCase', case_ids_in_couch, case_ids_in_sql, diff_count, num_docs_with_diffs, short, diffs_only
        )

        case_ids_in_couch = set(get_doc_ids_in_domain_by_type(
            domain, "CommCareCase-Deleted", XFormInstance.get_db())
        )
        case_ids_in_sql = set(CaseAccessorSQL.get_deleted_case_ids_in_domain(domain))
        diff_count, num_docs_with_diffs = diff_stats.pop("CommCareCase-Deleted", (0, 0))
        has_diffs |= self._print_status(
            'CommCareCase-Deleted', case_ids_in_couch, case_ids_in_sql,
            diff_count, num_docs_with_diffs, short, diffs_only
        )

        if diff_stats:
            for key, counts in diff_stats.items():
                diff_count, num_docs_with_diffs = counts
                has_diffs |= self._print_status(
                    key, set(), set(), diff_count, num_docs_with_diffs, short, diffs_only
                )

        if diffs_only and not has_diffs:
            print(shell_green("No differences found between old and new docs!"))
        return has_diffs
Example #13
0
 def testImportTrailingWhitespace(self):
     cols = ['case_id', 'age', u'sex\xa0', 'location']
     config = self._config(cols, named_columns=True)
     file = MockExcelFile(header_columns=cols, num_rows=2)
     res = do_import(file, config, self.domain)
     # we create 1 less since we knock off the header column
     self.assertEqual(1, res['created_count'])
     case_ids = get_case_ids_in_domain(self.domain)
     self.assertEqual(1, len(case_ids))
     case = CommCareCase.get(case_ids[0])
     self.assertTrue(bool(case.sex))  # make sure the value also got properly set
Example #14
0
    def get_all(self):
        status = self.status or CASE_STATUS_ALL
        if status == CASE_STATUS_ALL:
            case_ids = get_case_ids_in_domain(self.domain, type=self.case_type)
        elif status == CASE_STATUS_OPEN:
            case_ids = get_open_case_ids_in_domain(self.domain, type=self.case_type)
        elif status == CASE_STATUS_CLOSED:
            _assert = soft_assert('@'.join(['droberts', 'dimagi.com']))
            _assert(False, "I'm surprised CaseAPIHelper "
                           "ever gets called with status=closed")
            # this is rare so we don't care if it requires two calls to get
            # all the ids
            case_ids = (
                set(get_case_ids_in_domain(self.domain, type=self.case_type))
                - set(get_open_case_ids_in_domain(self.domain, type=self.case_type))
            )
        else:
            raise ValueError("Invalid value for 'status': '%s'" % status)

        return self._case_results(case_ids)
    def handle(self, domain, reason, **options):
        if should_use_sql_backend(domain):
            raise CommandError('This command only works for couch-based domains.')

        ids = get_case_ids_in_domain(domain)
        for count, case_id in enumerate(ids):
            try:
                rebuild_case_from_forms(domain, case_id, RebuildWithReason(reason=reason))
                if count % 100 == 0:
                    print('rebuilt %s/%s cases' % (count, len(ids)))
            except Exception as e:
                logging.exception("couldn't rebuild case {id}. {msg}".format(id=case_id, msg=str(e)))
Example #16
0
    def testCaseIdMatching(self):
        # bootstrap a stub case
        case = CommCareCase(domain=self.domain, type=self.default_case_type)
        case.importer_test_prop = 'foo'
        case.save()
        self.assertEqual(1, len(get_case_ids_in_domain(self.domain)))

        config = self._config(self.default_headers)
        file = MockExcelFile(header_columns=self.default_headers, num_rows=3, row_generator=id_match_generator(case._id))
        res = do_import(file, config, self.domain)
        self.assertEqual(0, res['created_count'])
        self.assertEqual(3, res['match_count'])
        self.assertFalse(res['errors'])

        # shouldn't create any more cases, just the one
        self.assertEqual(1, len(get_case_ids_in_domain(self.domain)))
        [case] = get_cases_in_domain(self.domain)
        for prop in self.default_headers[1:]:
            self.assertTrue(prop in case.get_case_property(prop))

        # shouldn't touch existing properties
        self.assertEqual('foo', case.importer_test_prop)
Example #17
0
    def testBlankRows(self):
        # don't create new cases for rows left blank
        config = self._config(['case_id', 'age', 'sex', 'location'], create_new_cases=True)
        file = make_worksheet_wrapper(
            ['case_id', 'age', 'sex', 'location'],
            [None, None, None, None],
            ['', '', '', ''],
        )
        res = do_import(file, config, self.domain)

        # no matching and no create new set - should do nothing
        self.assertEqual(0, res['created_count'])
        self.assertEqual(0, res['match_count'])
        self.assertEqual(0, len(get_case_ids_in_domain(self.domain)))
Example #18
0
    def testBlankRows(self):
        # don't create new cases for rows left blank
        config = self._config(self.default_headers, create_new_cases=True)
        file = MockExcelFile(
            header_columns=self.default_headers,
            num_rows=5,
            row_generator=blank_row_generator
        )
        res = do_import(file, config, self.domain)

        # no matching and no create new set - should do nothing
        self.assertEqual(0, res['created_count'])
        self.assertEqual(0, res['match_count'])
        self.assertEqual(0, len(get_case_ids_in_domain(self.domain)))
    def handle(self, *args, **options):
        if len(args) == 1:
            domain = args[0]
        else:
            raise CommandError('Usage: %s\n%s' % (self.args, self.help))

        ids = get_case_ids_in_domain(domain)
        for count, case_id in enumerate(ids):
            try:
                rebuild_case_from_forms(case_id)
                if count % 100 == 0:
                    print 'rebuilt %s/%s cases' % (count, len(ids))
            except Exception, e:
                logging.exception("couldn't rebuild case {id}. {msg}".format(id=case_id, msg=str(e)))
 def test_skip_user_case(self):
     caseblock = CaseBlock(
         create=True,
         case_id=uuid.uuid4().hex,
         user_id=self.user_id,
         owner_id=self.user_id,
         case_type='commcare-user',
     ).as_string()
     submit_case_blocks([caseblock], self.domain.name)
     self.assertEqual(1, len(get_case_ids_in_domain(self.domain.name)))
     explode_cases(self.user_id, self.domain.name, 10)
     cases_back = list(get_cases_in_domain(self.domain.name))
     self.assertEqual(1, len(cases_back))
     for case in cases_back:
         self.assertEqual(self.user_id, case.owner_id)
Example #21
0
 def testBasicChunking(self):
     config = self._config(['case_id', 'age', 'sex', 'location'])
     file = make_worksheet_wrapper(
         ['case_id', 'age', 'sex', 'location'],
         ['case_id-0', 'age-0', 'sex-0', 'location-0'],
         ['case_id-1', 'age-1', 'sex-1', 'location-1'],
         ['case_id-2', 'age-2', 'sex-2', 'location-2'],
         ['case_id-3', 'age-3', 'sex-3', 'location-3'],
         ['case_id-4', 'age-4', 'sex-4', 'location-4'],
     )
     res = do_import(file, config, self.domain, chunksize=2)
     # 5 cases in chunks of 2 = 3 chunks
     self.assertEqual(3, res['num_chunks'])
     self.assertEqual(5, res['created_count'])
     self.assertEqual(5, len(get_case_ids_in_domain(self.domain)))
Example #22
0
    def testNoCreateNew(self):
        config = self._config(['case_id', 'age', 'sex', 'location'], create_new_cases=False)
        file = make_worksheet_wrapper(
            ['case_id', 'age', 'sex', 'location'],
            ['case_id-0', 'age-0', 'sex-0', 'location-0'],
            ['case_id-1', 'age-1', 'sex-1', 'location-1'],
            ['case_id-2', 'age-2', 'sex-2', 'location-2'],
            ['case_id-3', 'age-3', 'sex-3', 'location-3'],
            ['case_id-4', 'age-4', 'sex-4', 'location-4'],
        )
        res = do_import(file, config, self.domain)

        # no matching and no create new set - should do nothing
        self.assertEqual(0, res['created_count'])
        self.assertEqual(0, res['match_count'])
        self.assertEqual(0, len(get_case_ids_in_domain(self.domain)))
Example #23
0
    def handle(self, *args, **options):
        if len(args) != 1:
            raise CommandError('Usage: %s\n%s' % (self.args, self.help))

        domain = args[0]
        case_ids = get_case_ids_in_domain(domain)

        print 'loading %s cases in %s' % (len(case_ids), domain)

        def stream_cases(all_case_ids):
            for case_ids in chunked(all_case_ids, 1000):
                for case in wrapped_docs(CommCareCase, keys=case_ids):
                # for case in CommCareCase.view('_all_docs', keys=case_ids, include_docs=True):
                    yield case

        count = 0
        for c in stream_cases(case_ids):
            count += 1
        print 'read %s cases' % count
Example #24
0
    def valiate_forms_and_cases(self, domain):
        form_ids_in_couch = set(get_form_ids_by_type(domain, 'XFormInstance'))
        form_ids_in_sqlite = set(self.planning_db.get_all_form_ids())

        print 'Forms in Couch: {}'.format(len(form_ids_in_couch))
        print 'Forms in Sqlite: {}'.format(len(form_ids_in_sqlite))
        if form_ids_in_couch ^ form_ids_in_sqlite:
            print 'In Couch only: {}'.format(
                list(form_ids_in_couch - form_ids_in_sqlite))

        case_ids_in_couch = set(get_case_ids_in_domain(domain))
        case_ids_in_sqlite = set(self.planning_db.get_all_case_ids())

        print 'Cases in Couch: {}'.format(len(case_ids_in_couch))
        print 'Cases in Sqlite: {}'.format(len(case_ids_in_sqlite))
        if case_ids_in_couch ^ case_ids_in_sqlite:
            print 'In Couch only: {}'.format(
                list(case_ids_in_couch - case_ids_in_sqlite))
            print 'In Sqlite only: {}'.format(
                list(case_ids_in_sqlite - case_ids_in_couch))
Example #25
0
    def obj_get_list(self, bundle, **kwargs):
        domain = kwargs['domain']
        include_closed = {
            'true': True,
            'false': False,
            'any': True
        }[bundle.request.GET.get('closed', 'false')]
        case_type = bundle.request.GET.get('case_type')

        key = [domain]
        if case_type:
            key.append(case_type)

        if include_closed:
            case_ids = get_case_ids_in_domain(domain, type=case_type)
        else:
            case_ids = get_open_case_ids_in_domain(domain, type=case_type)

        cases = imap(CommCareCase.wrap,
                     iter_docs(CommCareCase.get_db(), case_ids))
        return list(cases)
    def get_diff_stats(self, domain):
        db = get_diff_db(domain)
        diff_stats = db.get_diff_stats()

        stats = {}

        def _update_stats(doc_type, couch_count, sql_count):
            diff_count, num_docs_with_diffs = diff_stats.pop(doc_type, (0, 0))
            if diff_count or couch_count != sql_count:
                stats[doc_type] = (couch_count, sql_count, diff_count, num_docs_with_diffs)

        for doc_type in doc_types():
            form_ids_in_couch = len(set(get_form_ids_by_type(domain, doc_type)))
            form_ids_in_sql = len(set(FormAccessorSQL.get_form_ids_in_domain_by_type(domain, doc_type)))
            _update_stats(doc_type, form_ids_in_couch, form_ids_in_sql)

        form_ids_in_couch = len(set(get_doc_ids_in_domain_by_type(
            domain, "XFormInstance-Deleted", XFormInstance.get_db())
        ))
        form_ids_in_sql = len(set(FormAccessorSQL.get_deleted_form_ids_in_domain(domain)))
        _update_stats("XFormInstance-Deleted", form_ids_in_couch, form_ids_in_sql)

        case_ids_in_couch = len(set(get_case_ids_in_domain(domain)))
        case_ids_in_sql = len(set(CaseAccessorSQL.get_case_ids_in_domain(domain)))
        _update_stats("CommCareCase", case_ids_in_couch, case_ids_in_sql)

        if self.strict:
            # only care about these in strict mode
            case_ids_in_couch = len(set(get_doc_ids_in_domain_by_type(
                domain, "CommCareCase-Deleted", XFormInstance.get_db())
            ))
            case_ids_in_sql = len(set(CaseAccessorSQL.get_deleted_case_ids_in_domain(domain)))
            _update_stats("CommCareCase-Deleted", case_ids_in_couch, case_ids_in_sql)

        if diff_stats:
            for key in diff_stats.keys():
                _update_stats(key, 0, 0)

        return stats
Example #27
0
    def testExternalIdChunking(self):
        # bootstrap a stub case
        external_id = 'importer-test-external-id'

        headers = ['external_id', 'age', 'sex', 'location']
        config = self._config(headers, search_field='external_id')
        file = MockExcelFile(header_columns=headers, num_rows=3,
                             row_generator=id_match_generator(external_id))

        # the first one should create the case, and the remaining two should update it
        res = do_import(file, config, self.domain)
        self.assertEqual(1, res['created_count'])
        self.assertEqual(2, res['match_count'])
        self.assertFalse(res['errors'])
        self.assertEqual(2, res['num_chunks']) # the lookup causes an extra chunk

        # should just create the one case
        self.assertEqual(1, len(get_case_ids_in_domain(self.domain)))
        [case] = get_cases_in_domain(self.domain)
        self.assertEqual(external_id, case.external_id)
        for prop in self.default_headers[1:]:
            self.assertTrue(prop in case.get_case_property(prop))
    def test_parent_child(self):
        parent_id = uuid.uuid4().hex
        parent_type = 'exploder-parent-type'
        parent_block = CaseBlock(
            create=True,
            case_id=parent_id,
            user_id=self.user_id,
            owner_id=self.user_id,
            case_type=parent_type,
            version=V2
        ).as_string()

        child_id = uuid.uuid4().hex
        child_block = CaseBlock(
            create=True,
            case_id=child_id,
            user_id=self.user_id,
            owner_id=self.user_id,
            case_type='exploder-child-type',
            index={'parent': (parent_type, parent_id)},
            version=V2
        ).as_string()

        submit_case_blocks([parent_block, child_block], self.domain.name)
        self.assertEqual(2, len(get_case_ids_in_domain(self.domain.name)))

        explode_cases(self.user_id, self.domain.name, 5)
        cases_back = list(get_cases_in_domain(self.domain.name))
        self.assertEqual(10, len(cases_back))
        parent_cases = {p._id: p for p in filter(lambda case: case.type == parent_type, cases_back)}
        self.assertEqual(5, len(parent_cases))
        child_cases = filter(lambda case: case.type == 'exploder-child-type', cases_back)
        self.assertEqual(5, len(child_cases))
        child_indices = [child.indices[0].referenced_id for child in child_cases]
        # make sure they're different
        self.assertEqual(len(child_cases), len(set(child_indices)))
        for child in child_cases:
            self.assertEqual(1, len(child.indices))
            self.assertTrue(child.indices[0].referenced_id in parent_cases)
Example #29
0
 def testImportNone(self):
     res = bulk_import_async(self._config(), self.domain, None)
     self.assertEqual(
         'Sorry, your session has expired. Please start over and try again.',
         unicode(res['errors']))
     self.assertEqual(0, len(get_case_ids_in_domain(self.domain)))
Example #30
0
 def iter_case_ids_by_domain_and_type(domain, type_=None):
     return get_case_ids_in_domain(domain, type=type_)
Example #31
0
 def get_case_ids_in_domain(domain, type=None):
     return get_case_ids_in_domain(domain, type=type)
 def get_case_ids_in_domain(domain, type=None):
     return get_case_ids_in_domain(domain, type=type)
    def print_stats(self, domain, short=True, diffs_only=False):
        status = get_couch_sql_migration_status(domain)
        print("Couch to SQL migration status for {}: {}".format(domain, status))
        db = open_state_db(domain, self.state_dir)
        try:
            diff_stats = db.get_diff_stats()
        except OperationalError:
            diff_stats = {}

        has_diffs = False
        for doc_type in doc_types():
            form_ids_in_couch = set(get_form_ids_by_type(domain, doc_type))
            if doc_type == "XFormInstance":
                form_ids_in_couch.update(get_doc_ids_in_domain_by_type(
                    domain, "HQSubmission", XFormInstance.get_db()))
            form_ids_in_sql = set(FormAccessorSQL.get_form_ids_in_domain_by_type(domain, doc_type))
            diff_count, num_docs_with_diffs = diff_stats.pop(doc_type, (0, 0))
            has_diffs |= self._print_status(
                doc_type, form_ids_in_couch, form_ids_in_sql, diff_count, num_docs_with_diffs, short, diffs_only
            )

        form_ids_in_couch = set(get_doc_ids_in_domain_by_type(
            domain, "XFormInstance-Deleted", XFormInstance.get_db())
        )
        form_ids_in_sql = set(FormAccessorSQL.get_deleted_form_ids_in_domain(domain))
        diff_count, num_docs_with_diffs = diff_stats.pop("XFormInstance-Deleted", (0, 0))
        has_diffs |= self._print_status(
            "XFormInstance-Deleted", form_ids_in_couch, form_ids_in_sql,
            diff_count, num_docs_with_diffs, short, diffs_only
        )

        ZERO = Counts(0, 0)
        if db.has_doc_counts():
            doc_counts = db.get_doc_counts()
            couch_missing_cases = doc_counts.get("CommCareCase-couch", ZERO).missing
        else:
            doc_counts = None
            couch_missing_cases = 0
        for doc_type in CASE_DOC_TYPES:
            if doc_counts is not None:
                counts = doc_counts.get(doc_type, ZERO)
                case_ids_in_couch = db.get_missing_doc_ids(doc_type) if counts.missing else set()
                case_ids_in_sql = counts
            elif doc_type == "CommCareCase":
                case_ids_in_couch = set(get_case_ids_in_domain(domain))
                case_ids_in_sql = set(CaseAccessorSQL.get_case_ids_in_domain(domain))
            elif doc_type == "CommCareCase-Deleted":
                case_ids_in_couch = set(get_doc_ids_in_domain_by_type(
                    domain, "CommCareCase-Deleted", XFormInstance.get_db())
                )
                case_ids_in_sql = set(CaseAccessorSQL.get_deleted_case_ids_in_domain(domain))
            else:
                raise NotImplementedError(doc_type)
            diff_count, num_docs_with_diffs = diff_stats.pop(doc_type, (0, 0))
            has_diffs |= self._print_status(
                doc_type,
                case_ids_in_couch,
                case_ids_in_sql,
                diff_count,
                num_docs_with_diffs,
                short,
                diffs_only,
            )
            if doc_type == "CommCareCase" and couch_missing_cases:
                has_diffs = True
                print(shell_red("%s cases could not be loaded from Couch" % couch_missing_cases))
                if not short:
                    for case_id in db.get_missing_doc_ids("CommCareCase-couch"):
                        print(case_id)

        if diff_stats:
            for key, counts in diff_stats.items():
                diff_count, num_docs_with_diffs = counts
                has_diffs |= self._print_status(
                    key, set(), set(), diff_count, num_docs_with_diffs, short, diffs_only
                )

        if diffs_only and not has_diffs:
            print(shell_green("No differences found between old and new docs!"))
        return has_diffs
Example #34
0
 def test_get_case_ids_in_domain(self):
     self.assertEqual(
         set(get_case_ids_in_domain(self.domain)),
         {case.get_id
          for case in self.cases if case.domain == self.domain})