Improve backfill_orgs_and_org_courses output formatting (#25880)

The output was previously surfaced via `log.info` calls.
Given that the command is reporting on thousands of records,
that ended up being very difficult to parse.
Instead, print one organization or org-course linkage
per line.

Add example run of command with output to command
class docstring.

TNL-7774
This commit is contained in:
Kyle McCormick
2021-01-06 13:23:19 -05:00
committed by GitHub
parent 6adbbd2240
commit 70f910935c
2 changed files with 112 additions and 8 deletions

View File

@@ -39,6 +39,56 @@ class Command(BaseCommand):
> logo=None,
> active=True,
> )
Example run of command:
root@studio:/edx/app/edxapp/edx-platform# ./manage.py cms backfill_orgs_and_org_courses
<< ... lots of logging output ... >>
------------------------------------------------------
Dry-run of bulk-adding organizations...
Will create 5 organizations:
KyleX
KyleX2
KyleX3
KyleX4
KyleX5
Will reactivate 2 organizations:
BD04
BD05
------------------------------------------------------
Dry-run of bulk-adding organization-course linkages...
Will create 5 organization-course linkages:
kylex,course-v1:KyleX+OrgTest+1
kylex2,course-v1:KyleX2+OrgTest+1
kylex3,course-v1:KyleX3+OrgTest+1
kylex4,course-v1:KyleX4+OrgTest+1
kylex5,course-v1:KyleX5+OrgTest+1
Will reactivate 0 organization-course linkages:
------------------------------------------------------
Commit changes shown above to the database [y/n]? x
Commit changes shown above to the database [y/n]? yes
------------------------------------------------------
Bulk-adding organizations...
Created 5 organizations:
KyleX
KyleX2
KyleX3
KyleX4
KyleX5
Reactivated 2 organizations:
BD04
BD05
------------------------------------------------------
Bulk-adding organization-course linkages...
Created 5 organization-course linkages:
kylex,course-v1:KyleX+OrgTest+1
kylex2,course-v1:KyleX2+OrgTest+1
kylex3,course-v1:KyleX3+OrgTest+1
kylex4,course-v1:KyleX4+OrgTest+1
kylex5,course-v1:KyleX5+OrgTest+1
Reactivated 0 organization-course linkages:
------------------------------------------------------
root@studio:/edx/app/edxapp/edx-platform#
"""
# Make help message the first line of docstring.
@@ -85,10 +135,7 @@ class Command(BaseCommand):
if not confirm_changes(options, orgs, org_courseid_pairs):
print("No changes applied.")
return
print("Applying changes...")
organizations_api.bulk_add_organizations(orgs, dry_run=False)
organizations_api.bulk_add_organization_courses(org_courseid_pairs, dry_run=False)
print("Changes applied successfully.")
bulk_add_data(orgs, org_courseid_pairs, dry_run=False)
def confirm_changes(options, orgs, org_courseid_pairs):
@@ -111,8 +158,7 @@ def confirm_changes(options, orgs, org_courseid_pairs):
raise CommandError("Only one of 'apply' and 'dry' may be specified")
if options.get('apply'):
return True
organizations_api.bulk_add_organizations(orgs, dry_run=True)
organizations_api.bulk_add_organization_courses(org_courseid_pairs, dry_run=True)
bulk_add_data(orgs, org_courseid_pairs, dry_run=True)
if options.get('dry'):
return False
answer = ""
@@ -121,6 +167,52 @@ def confirm_changes(options, orgs, org_courseid_pairs):
return answer.lower().startswith('y')
def bulk_add_data(orgs, org_courseid_pairs, dry_run):
"""
Bulk-add the organizations and organization-course linkages.
Print out list of organizations and organization-course linkages,
one per line. We distinguish between records that are added by
being created vs. those that are being added by just reactivating an
existing record.
Arguments:
options (dict[str]): command-line arguments.
orgs (list[dict]): list of org data dictionaries to bulk-add.
org_courseid_pairs (list[tuple[dict, str]]):
list of (org data dictionary, course key string) links to bulk-add.
dry_run: Whether or not this run should be "dry" (ie, don't apply changes).
"""
adding_phrase = "Dry-run of bulk-adding" if dry_run else "Bulk-adding"
created_phrase = "Will create" if dry_run else "Created"
reactivated_phrase = "Will reactivate" if dry_run else "Reactivated"
print("------------------------------------------------------")
print(f"{adding_phrase} organizations...")
orgs_created, orgs_reactivated = organizations_api.bulk_add_organizations(
orgs, dry_run=dry_run
)
print(f"{created_phrase} {len(orgs_created)} organizations:")
for org_short_name in sorted(orgs_created):
print(f" {org_short_name}")
print(f"{reactivated_phrase} {len(orgs_reactivated)} organizations:")
for org_short_name in sorted(orgs_reactivated):
print(f" {org_short_name}")
print("------------------------------------------------------")
print(f"{adding_phrase} organization-course linkages...")
linkages_created, linkages_reactivated = organizations_api.bulk_add_organization_courses(
org_courseid_pairs, dry_run=dry_run
)
print(f"{created_phrase} {len(linkages_created)} organization-course linkages:")
for org_short_name, course_id in sorted(linkages_created):
print(f" {org_short_name},{course_id}")
print(f"{reactivated_phrase} {len(linkages_reactivated)} organization-course linkages:")
for org_short_name, course_id in sorted(linkages_reactivated):
print(f" {org_short_name},{course_id}")
print("------------------------------------------------------")
def find_orgslug_courseid_pairs():
"""
Returns the unique pairs of (organization short name, course run key string)

View File

@@ -140,8 +140,20 @@ class BackfillOrgsAndOrgCoursesTest(SharedModuleStoreTestCase):
},
)
@ddt.unpack
@patch.object(organizations_api, 'bulk_add_organizations')
@patch.object(organizations_api, 'bulk_add_organization_courses')
@patch.object(
# Mock out `bulk_add_organizations` to do nothing and return empty
# lists, indicating no organizations created or reactivated.
organizations_api,
'bulk_add_organizations',
return_value=([], []),
)
@patch.object(
# Mock out `bulk_add_organization_courses` to do nothing and return empty
# lists, indicating no linkages created or reactivated.
organizations_api,
'bulk_add_organization_courses',
return_value=([], []),
)
def test_arguments_and_input(
self,
mock_add_orgs,