0

为edX批量导入用户

 2 years ago
source link: http://wwj718.github.io/post/edx/edx-user-import/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

为edX批量导入用户

2016-07-13

–更新于:2016-07-13

近期重写这部分,使其成为django management command (在dogwood版本下测试可用)

原因有二,其一是之前所用的功能函数不完备,随着对edx的了解深入,想用更安全的函数来完成批量注册功能,其二是希望做到更好的内聚性

这部分是从我的edx_siteapi抽出的一个功能模块,edx_siteapi项目试图把edx的一些功能变为RESTful api接口(类似canvas做的),供外部系统调用和整合,有兴趣的小伙伴可以关注这个项目


在搭建edX的时候,可能面临一个这样的需求:批量导入学生作为用户。
即便是采用cas注册这个需求可能依旧存在,校内系统可能存有用户课程关系,需要预先导入,所以用户实体需要预先存在系统中,而cas是一种首次登录才注册的机制

有时我们可能需要批量从既有数据库中导入用户,尤其是将Open edX用于SPOC中时

在此给出一个可行的解决方案。

  • 从校方数据库中导出用户文件(csv格式)
  • 写脚本从csv文件中取得所需的字段(诸如学号,姓名)
  • 使用django management command将用户导入系统(利用django management command能调用django上下文的机制,这也是此次更新的主要地方)

##实施细节

我们假设从数据库导出的文件student.csv 如下

:::text
姓名,学号,email,专业,班级
张三,201011,[email protected],热能动力工程,动力1007班
李四,201012,[email protected],热能动力工程,动力1008班
王五,201013,[email protected],热能动力工程,动力1009班
...

注意逗号前后的空格是有影响的!

###编写脚本 在任意django app目录下创建management/commands/create_user_from_csv.py,先上代码

#!/usr/bin/env python
# encoding: utf-8
from optparse import make_option
from django.core.management.base import BaseCommand

from student.forms import AccountCreationForm
from student.models import create_comments_service_user
from student.views import _do_create_account, AccountValidationError
from track.management.tracked_command import TrackedCommand
# 解析csv
import unicodecsv  # utf-8 ,也可以用pandas:


def create_user(username, password, email, name):
    form = AccountCreationForm(data={
        'username': username,
        'email': email,
        'password': password,
        'name': name,
    },
                               tos_required=False)
    try:
        user, _, reg = _do_create_account(form)
        reg.activate()
        reg.save()
        #create_comments_service_user(user) #这会促发网络请求
        return user
    except AccountValidationError as e:
        print e.message


# wget https://raw.githubusercontent.com/edx/edx-platform/named-release/dogwood.rc/common/djangoapps/student/management/commands/create_user.py
class Command(TrackedCommand):
    help = """
    example:
        # Enroll a user [email protected] into the demo course
        # The username and name will default to "test"
        sudo -u www-data /edx/bin/python.edxapp /edx/app/edxapp/edx-platform/manage.py lms create_user_from_csv --help --settings devstack
        sudo -u www-data /edx/bin/python.edxapp /edx/app/edxapp/edx-platform/manage.py lms create_user_from_csv --csv /edx/app/edxapp/edx-platform/lms/djangoapps/siteapi/student.csv --settings devstack
    """
    help = u"批量导入用户"
    option_list = BaseCommand.option_list + (
        make_option('-c', '--csv', #采用绝对路径
                    metavar='CSV',
                    dest='csv',
                    default=None,
                    help=u'用户注册表'),
        )

    def handle(self, *args, **options):
        csv = options['csv']
        with open(csv) as f:
            f_csv = unicodecsv.DictReader(f, encoding='utf-8')
            for item in f_csv:
                print item[u"姓名"]
                username = item[u"学号"]
                email = item[u"email"]
                name = item[u"姓名"]
                password = username
                create_user(username, password, email, name)
        # 缺乏读写csv的技巧,next和边界,按header读取
        # http://python3-cookbook.readthedocs.io/zh_CN/latest/c06/p01_read_write_csv_data.html

测试显示,8000名学生的话,大约需要导入十几分钟(旧版本)

###安装依赖

:::text
sudo /edx/bin/pip.edxapp install unicodecsv #dogwood版不需要

###开始导入 sudo -u www-data /edx/bin/python.edxapp /edx/app/edxapp/edx-platform/manage.py lms create_user_from_csv --csv /tmp/student.csv --settings devstack

###开始使用 在/login中使用email和password登录即可。

对于不想使用这种登录方式的,可以自己来写用户认证,诸如使用username和password登录之类的

###后记 文中我们创建用户使用的是python代码。

如果是单独创建用户,也可以用

sudo -u www-data /edx/bin/python.edxapp /edx/app/edxapp/edx-platform/manage.py lms  create_user --username test123 --name test123  --password test123 --email [email protected] 

如果你愿意也可以采用http请求创建,详情可以跟踪sysadmin里的创建用户功能(封装成restful接口可用作异构系统接口)

删除用户之后创建同名用户,会造成:CommentClientRequestError: u’[“Username is already taken”]’,猜测是评论系统内依然留存有用户造成的,而评论系统是个异构系统(mongodb)

  • import lms.lib.comment_client as cc
  • cc_user = cc.User.from_django_user(user)

如果我们的猜测是对的,应该只要删除点mongodb中的user应该就好了

:::text
mongo
use cs_comments_service_development
db.users.find()
db.users.remove({}) #移除所有,也可以写到python脚本里,使用pymongo

一切正常,猜测正确!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK