Skip to content

Commit

Permalink
Merge pull request #17440 from code-dot-org/studioPersonScript
Browse files Browse the repository at this point in the history
Add CSV support for studio_people script.
  • Loading branch information
ashercodeorg committed Aug 31, 2017
2 parents 10eab6f + 6b04495 commit 2fbd035
Showing 1 changed file with 62 additions and 15 deletions.
77 changes: 62 additions & 15 deletions bin/oneoff/backfill_data/studio_people
Original file line number Diff line number Diff line change
@@ -1,31 +1,78 @@
#!/usr/bin/env ruby

# This script creates a StudioPerson (if one does not already exist) for every teacher.
# This script creates a StudioPerson (if one does not already exist) for every teacher. It can be
# run with or without a CSV file. If there is no file, the script iterates over all users, creating
# StudioPerson's as necessary. If there is a file, the script creates StudioPersons for the users
# specified in the file.
#
# The CSV for production was created by the following SQL query.
#
# SELECT id
# FROM users
# WHERE user_type = "teacher" AND studio_person_id IS NULL;
#
# USAGE: ./bin/oneoff/backfill_data/studio_people
# ./bin/oneoff/backfill_data/studio_people studio_people_data.csv

require 'csv'
require_relative '../../../dashboard/config/environment'

# The user_id variable is used to track the in-progress user in case of an exception.
user_id = 0

begin
# Unfortunately, this query will not be peformant as the result of no index existing on
# users.user_type. As we are batching (via find_each), this should not impact live site traffic.
# And since we are willing to allow this script to run for hours, we are fine with this.
User.
with_deleted.
where(studio_person_id: nil).
where(user_type: User::TYPE_TEACHER).
find_each do |user|
user_id = user.id
# Depending on whether a filename is specified (via ARGV[0]), we iterate over all users or over
# the filename, creating StudioPerson's as necessary.
if ARGV[0].nil?
# Unfortunately, this query will not be peformant as the result of no index existing on
# users.user_type. As we are batching (via find_each), this should not impact users of the site.
# It may take a long time for the DB updates to occur, though.
User.
with_deleted.
where(studio_person_id: nil).
where(user_type: User::TYPE_TEACHER).
find_each do |user|
user_id = user.id

puts "PROCESSING ID: #{user_id}..." unless user_id % 10_000
puts "PROCESSING ID: #{user_id}..." unless user_id % 10_000

user.update!(
studio_person: (
user.email ? StudioPerson.create!(emails: user.email) : StudioPerson.create!
user.update!(
studio_person: (
user.email ? StudioPerson.create!(emails: user.email) : StudioPerson.create!
)
)
)
end
else
filename = ARGV[0]

CSV.foreach(filename, headers: true) do |row|
puts "ROW: #{row}"
user_id = row['id']

puts "PROCESSING ID: #{user_id}..." unless user_id % 10_000

user = User.with_deleted.find_by_id(user_id)

# This shouldn't happen... But just in case.
unless user
puts "MISSING USER: #{user_id}"
next
end
# This may happen if a user is saved (with callbacks) between when the CSV was generated and
# the script was run.
if user.studio_person_id
puts "UNNECESSARY USER: #{user_id}"
next
end
# This may happen if a user changes between when the CSV was generated and the script was run.
if user.user_type == 'student'
puts "STUDENT USER: #{user_id}"
next
end

user.update!(studio_person: StudioPerson.create!(emails: user.email))
end
end
rescue Exception => e
puts "EXCEPTION (ID: #{user_id}): #{e.message}"
raise e
Expand Down

0 comments on commit 2fbd035

Please sign in to comment.