Change all docs filenames to .adoc
[working/Evergreen.git] / docs / admin_initial_setup / migrating_patron_data.adoc
1 Migrating Patron Data
2 =====================
3
4 This section will explain the task of migrating your patron data from comma
5 delimited files into Evergreen. It does not deal with the process of exporting
6 from the non-Evergreen system since this process may vary depending on where you
7 are extracting your patron records. Patron could come from an ILS or it could
8 come from a student database in the case of academic records.
9
10 When importing records into Evergreen you will need to populate 3 tables in your
11 Evergreen database:
12
13 * actor.usr - The main table for user data 
14 * actor.card - Stores the barcode for users; Users can have more than 1 card but 
15 only 1 can be active at a given time; 
16 * actor.usr_address - Used for storing address information; A user can
17 have more than one address.
18
19 Before following the procedures below to import patron data into Evergreen, it
20 is a good idea to examine the fields in these tables in order to decide on a
21 strategy for data to include in your import. It is important to understand the
22 data types and constraints on each field.
23
24 . Export the patron data from your existing ILS or from another source into a
25 comma delimited file. The comma delimited file used for importing the records
26 should use Unicode (UTF8) character encoding.
27
28 . Create a staging table. A staging table will allow you to tweak the data before 
29 importing. Here is an example sql statement:
30 +
31 [source,sql]
32 ----------------------------------
33     CREATE TABLE students (
34          student_id int, barcode text, last_name text, first_name text, email text, 
35                  address_type text, street1 text, street2 text, 
36         city text, province text, country text, postal_code text, phone text, profile 
37         int DEFAULT 2, ident_type int, home_ou int, claims_returned_count int DEFAULT 
38                 0, usrname text, net_access_level int DEFAULT 2, password text
39     ); 
40 -----------------------------------
41 +
42 NOTE: The _default_ variables allow you to set default for your library or to populate 
43 required fields in Evergreen if your data includes NULL values.
44 +
45 The data field profile in the above SQL script refers to the user group and should be an 
46 integer referencing the id field in permission.grp_tree. Setting this value will affect 
47 the permissions for the user. See the values in permission.grp_tree for possibilities.
48 +
49 ident_type is the identification type used for identifying users. This is a integer value 
50 referencing config.identification_type and should match the id values of that table. The 
51 default values are 1 for Drivers License, 2 for SSN or 3 for other.
52 +
53 home_ou is the home organizational unit for the user. This value needs to match the 
54 corresponding id in the actor.org_unit table.
55 +
56 . Copy records into staging table from a comma delimited file.
57 +
58 [source,sql]
59 ----------------------------------
60     COPY students (student_id, last_name, first_name, email, address_type, street1, street2, 
61         city, province, country, postal_code, phone) 
62         FROM '/home/opensrf/patrons.csv' 
63                 WITH CSV HEADER;  
64 -----------------------------------
65 +
66 The script will vary depending on the format of your patron load file (patrons.csv). 
67 +
68 . Formatting of some fields to fit Evergreen filed formatting may be required. Here is an example 
69 of sql to adjust phone numbers in the staging table to fit the evergreen field:
70 +
71 [source,sql]
72 ----------------------------------
73     UPDATE students phone = replace(replace(replace(rpad(substring(phone from 1 for 9), 10, '-') || 
74     substring(phone from 10), '(', ''), ')', ''), ' ', '-');
75 ----------------------------------
76 +
77 Data ``massaging'' will be required to fit formats used in Evergreen.
78 +
79 . Insert records from the staging table into the actor.usr Evergreen table:
80 +
81 [source,sql]
82 ----------------------------------
83      INSERT INTO actor.usr (
84         profile, usrname, email, passwd, ident_type, ident_value, first_given_name, 
85         family_name, day_phone, home_ou, claims_returned_count, net_access_level) 
86         SELECT profile, students.usrname, email, password, ident_type, student_id, 
87         first_name, last_name, phone, home_ou, claims_returned_count, net_access_level 
88         FROM students;
89 ----------------------------------
90 +
91 . Insert records into actor.card from actor.usr .
92 +
93 [source,sql]
94 ----------------------------------
95     INSERT INTO actor.card (usr, barcode) 
96         SELECT actor.usr.id, students.barcode 
97         FROM students 
98                 INNER JOIN actor.usr 
99                         ON students.usrname = actor.usr.usrname;
100 ----------------------------------
101 +
102 This assumes a one to one card patron relationship. If your patron data import has multiple cards 
103 assigned to one patron more complex import scripts may be required which look
104 for inactive or active flags.
105 +
106 . Update actor.usr.card field with actor.card.id to associate active card with the user:
107 +
108 [source,sql]
109 ----------------------------------
110     UPDATE actor.usr 
111         SET card = actor.card.id 
112         FROM actor.card 
113         WHERE actor.card.usr = actor.usr.id;
114 ----------------------------------
115 +
116 . Insert records into actor.usr_address to add address information for users:
117 +
118 [source,sql]
119 ----------------------------------
120     INSERT INTO actor.usr_address (usr, street1, street2, city, state, country, post_code) 
121         SELECT actor.usr.id, students.street1, students.street2, students.city, students.province, 
122         students.country, students.postal_code 
123         FROM students 
124         INNER JOIN actor.usr ON students.usrname = actor.usr.usrname;
125 ----------------------------------
126 +
127 . Update actor.usr.address with address id from address table.
128
129 [source,sql]
130 ----------------------------------
131     UPDATE actor.usr 
132         SET mailing_address = actor.usr_address.id, billing_address = actor.usr_address.id 
133         FROM actor.usr_address 
134         WHERE actor.usr.id = actor.usr_address.usr;
135 ----------------------------------
136
137 This assumes 1 address per patron. More complex scenarios may require more sophisticated SQL.
138
139 Creating an sql Script for Importing Patrons
140 --------------------------------------------
141
142 The procedure for importing patron can be automated with the help of an sql script. Follow these 
143 steps to create an import script:
144
145 . Create an new file and name it import.sql
146 . Edit the file to look similar to this:
147
148 [source,sql]
149 ----------------------------------
150     BEGIN;
151
152     -- Create staging table.
153     CREATE TABLE students (
154         student_id int, barcode text, last_name text, first_name text, email text, address_type text, 
155                 street1 text, street2 text, city text, province text, country text, postal_code text, phone 
156                 text, profile int, ident_type int, home_ou int, claims_returned_count int DEFAULT 0, usrname text, 
157         net_access_level int DEFAULT 2, password text
158     ); 
159
160     --Copy records from your import text file
161     COPY students (student_id, last_name, first_name, email, address_type, street1, street2, city, province, 
162         country, postal_code, phone, password) 
163         FROM '/home/opensrf/patrons.csv' WITH CSV HEADER;  
164
165
166     --Insert records from the staging table into the actor.usr table.
167     INSERT INTO actor.usr (
168         profile, usrname, email, passwd, ident_type, ident_value, first_given_name, family_name, 
169         day_phone, home_ou, claims_returned_count, net_access_level) 
170         SELECT profile, students.usrname, email, password, ident_type, student_id, first_name, 
171         last_name, phone, home_ou, claims_returned_count, net_access_level FROM students;
172
173     --Insert records from the staging table into the actor.usr table.
174     INSERT INTO actor.card (usr, barcode) 
175         SELECT actor.usr.id, students.barcode 
176         FROM students 
177                 INNER JOIN actor.usr 
178                         ON students.usrname = actor.usr.usrname;
179
180     --Update actor.usr.card field with actor.card.id to associate active card with the user:
181     UPDATE actor.usr 
182         SET card = actor.card.id 
183         FROM actor.card 
184         WHERE actor.card.usr = actor.usr.id;
185
186     --INSERT records INTO actor.usr_address from staging table.
187     INSERT INTO actor.usr_address (usr, street1, street2, city, state, country, post_code) 
188         SELECT actor.usr.id, students.street1, students.street2, students.city, students.province, 
189         students.country, students.postal_code 
190         FROM students 
191         INNER JOIN actor.usr ON students.usrname = actor.usr.usrname;
192
193
194    --Update actor.usr mailing address with id from actor.usr_address table.:
195     UPDATE actor.usr 
196         SET mailing_address = actor.usr_address.id, billing_address = actor.usr_address.id 
197         FROM actor.usr_address 
198         WHERE actor.usr.id = actor.usr_address.usr;
199
200     COMMIT;
201 ----------------------------------
202
203 Placing the sql statements between BEGIN; and COMMIT; creates a transaction
204 block so that if any sql statements fail, the entire process is canceled and the
205 database is rolled back to its original state. Lines beginning with -- are
206 comments to let you you what each sql statement is doing and are not processed.
207
208 Batch Updating Patron Data
209 --------------------------
210
211 For academic libraries, doing batch updates to add new patrons to the Evergreen
212 database is a critical task. The above procedures and import script can be
213 easily adapted to create an update script for importing new patrons from
214 external databases. If the data import file contains only new patrons, then, the
215 above procedures will work well to insert those patrons. However, if the data
216 load contains all patrons, a second staging table and a procedure to remove
217 existing patrons from that second staging table may be required before importing
218 the new patrons. Moreover, additional steps to update address information and
219 perhaps delete inactive patrons may also be desired depending on the
220 requirements of the institution.
221
222 After developing the scripts to import and update patrons have been created,
223 another important task for library staff is to develop an import strategy and
224 schedule which suits the needs of the library. This could be determined by
225 registration dates of your institution in the case of academic libraries. It is
226 important to balance the convenience of patron loads and the cost of processing
227 these loads vs staff adding patrons manually.
228