Merge lp:~j-corwin/openlp/migration into lp:openlp

Proposed by Raoul Snyman
Status: Merged
Approved by: Raoul Snyman
Approved revision: no longer in the revision history of the source branch.
Merged at revision: not available
Proposed branch: lp:~j-corwin/openlp/migration
Merge into: lp:openlp
Diff against target: None lines
To merge this branch: bzr merge lp:~j-corwin/openlp/migration
Reviewer Review Type Date Requested Status
Tim Bentley Approve
Raoul Snyman approve Approve
Review via email: mp+6131@code.launchpad.net

This proposal supersedes a proposal from 2009-05-02.

To post a comment you must log in.
Revision history for this message
Jonathan Corwin (j-corwin) wrote : Posted in a previous version of this proposal

Attempt to fix song migration so it matches current file definitions.
Remove the need to edit the dmp file as part of the migration

Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Muhahaha! The Style Police has arrived!

(Yes, this is mostly old code, but it needs to be said!)

All strings are single-quoted and unicode:

  self.display.output("Songs processing started")

  should be:

  self.display.output(u'Songs processing started')

Why are you adding columns one at a time?

  conn.execute("""create table authors (id integer primary key ASC AUTOINCREMENT);""")
  conn.commit()
  self.display.sub_output("authors table created")
  conn.execute("""alter table authors add column first_name varchar(128);""")
  conn.commit()
  self.display.sub_output("first_name added")
  conn.execute("""alter table authors add column last_name varchar(128);""")
  conn.commit()

  Shouldn't that rather be:

  conn.execute("""
    create table authors (
      id integer primary key ASC AUTOINCREMENT,
      first_name varchar(128),
      last_name varchar(128),
      display_name varchar(255)
    );""")
  conn.commit()
  self.display.sub_output("authors table created")

Also name variables better:

  # I'm not sure what these two variables are supposed to be
  def run_cmd(self, cmd):
      f_i, f_o = os.popen4(cmd)

review: Needs Fixing
Revision history for this message
Jonathan Corwin (j-corwin) wrote : Posted in a previous version of this proposal

On Sat, May 2, 2009 at 9:31 PM, Raoul Snyman <
<email address hidden>> wrote:

> Review: Needs Fixing
> Muhahaha! The Style Police has arrived!
>
> (Yes, this is mostly old code, but it needs to be said!)
>
> All strings are single-quoted and unicode:
>
> self.display.output("Songs processing started")
>
> should be:
>
> self.display.output(u'Songs processing started')

Was already there, nowt to do with me

>
> Why are you adding columns one at a time?
>
> conn.execute("""create table authors (id integer primary key ASC
> AUTOINCREMENT);""")
> conn.commit()
> self.display.sub_output("authors table created")
> conn.execute("""alter table authors add column first_name
> varchar(128);""")
> conn.commit()
> self.display.sub_output("first_name added")
> conn.execute("""alter table authors add column last_name varchar(128);""")
> conn.commit()
>
> Shouldn't that rather be:

> conn.execute("""
> create table authors (
> id integer primary key ASC AUTOINCREMENT,
> first_name varchar(128),
> last_name varchar(128),
> display_name varchar(255)
> );""")
> conn.commit()
> self.display.sub_output("authors table created")

I agree, but again was just copying what was already there since I didn't
know if the original author had done it that way on purpose

>
> Also name variables better:
>
> # I'm not sure what these two variables are supposed to be
> def run_cmd(self, cmd):
> f_i, f_o = os.popen4(cmd)

I didn't touch this function and have no idea what it does.

All I was doing was updating existing code so it worked... I wasn't planning
on rewriting the whole existing
module.

Revision history for this message
Jonathan Corwin (j-corwin) wrote : Posted in a previous version of this proposal

> Muhahaha! The Style Police has arrived!

Changes pushed.

Revision history for this message
Raoul Snyman (raoul-snyman) wrote :

Yes, I know it's not your code, but I'm just saying this for the record...

Use the os.path module functions, they tend to take care of little things:

  conn = sqlite3.connect(self.data_path + os.sep + database)

  should rather be:

  conn = sqlite3.connect(os.path.join(self.data_path, database))

Indices really should have functional names... "author1" is not a good name:

  conn.execute("""create index if not exists author1 on authors (display_name ASC,id ASC);""")

  better:

  conn.execute("""create index if not exists author_display_name on authors (display_name ASC,id ASC);""")

I'm a little wary of all these "replace"s - there's probably a better way...

  replace(replace(replace(replace(replace(replace(replace(replace(

review: Approve (approve)
Revision history for this message
Tim Bentley (trb143) wrote :

Not user about replace(replace(replace as it's done is SQL then thats life

Does this handle Unicode character sets. If it does it simplifes the database migration process.

review: Approve
Revision history for this message
Jonathan Corwin (j-corwin) wrote :

On Sun, May 3, 2009 at 12:37 AM, Raoul Snyman <
<email address hidden>> wrote:
y.

>
> I'm a little wary of all these "replace"s - there's probably a better
> way...
>
> replace(replace(replace(replace(replace(replace(replace(replace(
>
> In the original code it was done in the python as lots of individual
replaces. However the python process of selecting 3000 records (in my case)
and updating each one individually took over 5 minutes on my machine.
Doing it in sqlite direct took 5 seconds...

I agree it doesn't look pretty though.

Jonathan.

lp:~j-corwin/openlp/migration updated
439. By Raoul Snyman

Added images

440. By Raoul Snyman

Merged Jonathan Corwin's changes to the database migration script.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/migration/migratesongs.py'
2--- openlp/migration/migratesongs.py 2009-02-04 20:16:56 +0000
3+++ openlp/migration/migratesongs.py 2009-05-02 21:40:10 +0000
4@@ -31,231 +31,210 @@
5 clear_mappers()
6 mapper(Author, authors_table)
7 mapper(Book, song_books_table)
8-mapper(Song, songs_table,
9- properties={'authors': relation(Author, backref='songs',
10- secondary=authors_songs_table),
11- 'book': relation(Book, backref='songs'),
12- 'topics': relation(Topic, backref='songs',
13- secondary=songs_topics_table)})
14+mapper(Song, songs_table, properties={
15+ 'authors': relation(Author, backref='songs',
16+ secondary=authors_songs_table),
17+ 'book': relation(Book, backref='songs'),
18+ 'topics': relation(Topic, backref='songs',
19+ secondary=songs_topics_table)})
20 mapper(Topic, topics_table)
21
22 class MigrateSongs():
23 def __init__(self, display):
24 self.display = display
25- self.config = PluginConfig("Songs")
26+ self.config = PluginConfig('Songs')
27 self.data_path = self.config.get_data_path()
28- self.database_files = self.config.get_files("sqlite")
29+ self.database_files = self.config.get_files('sqlite')
30 print self.database_files
31
32 def process(self):
33- self.display.output("Songs processing started");
34+ self.display.output(u'Songs processing started')
35 for f in self.database_files:
36 self.v_1_9_0(f)
37- self.display.output("Songs processing finished");
38+ self.display.output(u'Songs processing finished')
39
40 def v_1_9_0(self, database):
41- self.display.output("Migration 1.9.0 Started for "+database);
42+ self.display.output(u'Migration 1.9.0 Started for ' + database)
43 self._v1_9_0_authors(database)
44 self._v1_9_0_topics(database)
45 self._v1_9_0_songbook(database)
46 self._v1_9_0_songauthors(database)
47 self._v1_9_0_songtopics(database)
48 self._v1_9_0_songs(database)
49- self._v1_9_0_songs_update(database)
50-
51- self.display.output("Migration 1.9.0 Finished for " + database);
52+ self.display.output(u'Migration 1.9.0 Finished for ' + database)
53
54 def _v1_9_0_authors(self, database):
55- self.display.sub_output("Authors Started for "+database);
56- conn = sqlite3.connect(self.data_path+os.sep+database)
57+ self.display.sub_output(u'Authors Started for ' + database)
58+ conn = sqlite3.connect(self.data_path + os.sep + database)
59 conn.execute("""alter table authors rename to authors_temp;""")
60 conn.commit()
61-
62- conn.execute("""create table authors add column display_name varchar(255);""")
63- conn.commit()
64- self.display.sub_output("first name created")
65- conn.execute("""alter table authors add column first_name varchar(128);""")
66- conn.commit()
67- self.display.sub_output("first name created")
68- conn.execute("""alter table authors add column last_name varchar(128);""")
69- conn.commit()
70- self.display.sub_output("last name created")
71- conn.execute("""create index if not exists author_display_name on authors (display_name ASC,id ASC);""")
72- conn.commit()
73- self.display.sub_output("index author1 created")
74- conn.execute("""create index if not exists author_last_name on authors (last_name ASC,id ASC);""")
75- conn.commit()
76- self.display.sub_output("index author2 created")
77- conn.execute("""create index if not exists author_first_name on authors (first_name ASC,id ASC);""")
78- conn.commit()
79- self.display.sub_output("index author3 created")
80- self.display.sub_output("Author Data Migration started")
81- c = conn.cursor()
82- text = c.execute("""select * from authors """) .fetchall()
83+ self.display.sub_output(u'old author renamed to author_temp')
84+ conn.execute("""create table authors (
85+ id integer primary key ASC AUTOINCREMENT,
86+ first_name varchar(128),
87+ last_name varchar(128),
88+ display_name varchar(255)
89+ );""")
90+ conn.commit()
91+ self.display.sub_output(u'authors table created')
92+ conn.execute("""create index if not exists author1 on authors
93+ (display_name ASC,id ASC);""")
94+ conn.commit()
95+ self.display.sub_output(u'index author1 created')
96+ conn.execute("""create index if not exists author2 on authors
97+ (last_name ASC,id ASC);""")
98+ conn.commit()
99+ self.display.sub_output(u'index author2 created')
100+ conn.execute("""create index if not exists author3 on authors
101+ (first_name ASC,id ASC);""")
102+ conn.commit()
103+ self.display.sub_output(u'index author3 created')
104+ self.display.sub_output(u'Author Data Migration started')
105+ conn.execute("""insert into authors (id, display_name)
106+ select authorid, authorname from authors_temp;""")
107+ conn.commit()
108+ self.display.sub_output(u'authors populated')
109+ c = conn.cursor()
110+ text = c.execute("""select * from authors""") .fetchall()
111 for author in text:
112- dispname = author[1]
113- if author[2] == None:
114- dispname = dispname.replace("'", "") # remove quotes.
115- pos = dispname.rfind(" ")
116- afn = dispname[:pos]
117- aln = dispname[pos + 1:len(dispname)]
118- #txt = text[2]
119- s = "update authors set display_name = '" + dispname + "', first_name = '" + afn + "', last_name = '" + aln + "' where id = " +str(author[0])
120- text1 = c.execute(s)
121- conn.commit()
122- conn.execute("""alter table authors drop column authorname;""")
123- conn.commit()
124- conn.close()
125- self.display.sub_output("Author Data Migration Completed")
126- self.display.sub_output("Authors Completed");
127+ dispname = author[3]
128+ dispname = dispname.replace("'", "")
129+ pos = dispname.rfind(" ")
130+ authorfirstname = dispname[:pos]
131+ authorlastname = dispname[pos + 1:len(dispname)]
132+ s = "update authors set first_name = '" \
133+ + authorfirstname + "', last_name = '" + authorlastname \
134+ + "' where id = " + str(author[0])
135+ c.execute(s)
136+ conn.commit()
137+ self.display.sub_output(u'Author Data Migration Completed')
138+ conn.execute("""drop table authors_temp;""")
139+ conn.commit()
140+ conn.close()
141+ self.display.sub_output(u'author_temp dropped')
142+ self.display.sub_output(u'Authors Completed')
143+
144+ def _v1_9_0_songbook(self, database):
145+ self.display.sub_output(u'SongBook Started for ' + database)
146+ conn = sqlite3.connect(self.data_path + os.sep + database)
147+ conn.execute("""create table if not exists song_books (
148+ id integer Primary Key ASC AUTOINCREMENT,
149+ name varchar(128),
150+ publisher varchar(128)
151+ );""")
152+ conn.commit()
153+ self.display.sub_output(u'songbook table created')
154+ conn.execute("""create index if not exists songbook1 on song_books (name ASC,id ASC);""")
155+ conn.commit()
156+ self.display.sub_output(u'index songbook1 created')
157+ conn.execute("""create index if not exists songbook2 on song_books (publisher ASC,id ASC);""")
158+ conn.commit()
159+ conn.close()
160+ self.display.sub_output(u'index songbook2 created')
161+ self.display.sub_output(u'SongBook Completed')
162+
163+ def _v1_9_0_songs(self, database):
164+ self.display.sub_output(u'Songs Started for ' + database)
165+ conn = sqlite3.connect(self.data_path + os.sep + database)
166+ conn.execute("""alter table songs rename to songs_temp;""")
167+ conn.commit()
168+ conn.execute("""create table if not exists songs (
169+ id integer Primary Key ASC AUTOINCREMENT,
170+ song_book_id integer,
171+ title varchar(255),
172+ lyrics text,
173+ verse_order varchar(128),
174+ copyright varchar(255),
175+ comments text,
176+ ccli_number varchar(64),
177+ song_number varchar(64),
178+ theme_name varchar(128),
179+ search_title varchar(255),
180+ search_lyrics text
181+ );""")
182+ conn.commit()
183+ self.display.sub_output(u'songs table created')
184+ conn.execute("""create index if not exists songs1 on songs
185+ (search_lyrics ASC,id ASC);""")
186+ conn.commit()
187+ self.display.sub_output(u'index songs1 created')
188+ conn.execute("""create index if not exists songs2 on songs
189+ (search_title ASC,id ASC);""")
190+ conn.commit()
191+ self.display.sub_output(u'index songs2 created')
192+ conn.execute("""insert into songs (id, title, lyrics, copyright,
193+ search_title, search_lyrics, song_book_id)
194+ select songid, songtitle, lyrics, copyrightinfo,
195+ replace(replace(replace(replace(replace(replace(replace(replace(
196+ replace(songtitle, '&', 'and'), ',', ''), ';', ''), ':', ''),
197+ '(', ''), ')', ''), '{', ''), '}',''),'?',''),
198+ replace(replace(replace(replace(replace(replace(replace(replace(
199+ replace(lyrics, '&', 'and'), ',', ''), ';', ''), ':', ''),
200+ '(', ''), ')', ''), '{', ''), '}',''),'?',''),
201+ 0
202+ from songs_temp;""")
203+ conn.commit()
204+ self.display.sub_output(u'songs populated')
205+ conn.execute("""drop table songs_temp;""")
206+ conn.commit()
207+ conn.close()
208+ self.display.sub_output(u'songs_temp dropped')
209+ self.display.sub_output(u'Songs Completed')
210
211 def _v1_9_0_topics(self, database):
212- self.display.sub_output("Topics Started for "+database);
213+ self.display.sub_output(u'Topics Started for ' + database)
214 conn = sqlite3.connect(self.data_path+os.sep+database)
215 conn.text_factory = str
216- conn.execute("""create table if not exists topics (id integer Primary Key ASC AUTOINCREMENT);""")
217- conn.commit()
218- self.display.sub_output("Topic table created")
219- conn.execute("""alter table topics add column name varchar(128);""")
220- conn.commit()
221- self.display.sub_output("topicname added")
222+ conn.execute("""create table if not exists topics
223+ (id integer Primary Key ASC AUTOINCREMENT,
224+ name varchar(128));""")
225+ conn.commit()
226+ self.display.sub_output(u'Topic table created')
227 conn.execute("""create index if not exists topic1 on topics (name ASC,id ASC);""")
228 conn.commit()
229 conn.close()
230- self.display.sub_output("index topic1 created")
231-
232- self.display.sub_output("Topics Completed");
233-
234- def _v1_9_0_songbook(self, database):
235- self.display.sub_output("SongBook Started for "+database);
236- conn = sqlite3.connect(self.data_path+os.sep+database)
237- conn.execute("""create table if not exists song_books (id integer Primary Key ASC AUTOINCREMENT);""")
238- conn.commit()
239- self.display.sub_output("SongBook table created")
240- conn.execute("""alter table song_books add column name varchar(128);""")
241- conn.commit()
242- self.display.sub_output("songbook_name added")
243- conn.execute("""alter table song_books add column publisher varchar(128);""")
244- conn.commit()
245- self.display.sub_output("songbook_publisher added")
246- conn.execute("""create index if not exists songbook1 on song_books (name ASC,id ASC);""")
247- conn.commit()
248- self.display.sub_output("index songbook1 created")
249- conn.execute("""create index if not exists songbook2 on song_books (publisher ASC,id ASC);""")
250- conn.commit()
251+ self.display.sub_output(u'index topic1 created')
252+
253+ self.display.sub_output(u'Topics Completed')
254+
255+ def _v1_9_0_songauthors(self, database):
256+ self.display.sub_output(u'SongAuthors Started for ' + database);
257+ conn = sqlite3.connect(self.data_path + os.sep + database)
258+ conn.execute("""create table if not exists authors_songs
259+ (author_id integer,
260+ song_id integer);""")
261+ conn.commit()
262+ self.display.sub_output(u'authors_songs table created')
263+ conn.execute("""insert into authors_songs (author_id, song_id)
264+ select authorid, songid from songauthors;""")
265+ conn.commit()
266+ self.display.sub_output(u'authors_songs populated')
267+ conn.execute("""drop table songauthors;""")
268+ conn.commit()
269+ self.display.sub_output(u'songauthors dropped')
270 conn.close()
271- self.display.sub_output("index songbook2 created")
272- self.display.sub_output("SongBook Completed");
273+ self.display.sub_output(u'SongAuthors Completed')
274
275 def _v1_9_0_songtopics(self, database):
276- self.display.sub_output("Songtopics Started for "+database);
277+ self.display.sub_output(u'Songtopics Started for ' + database);
278 conn = sqlite3.connect(self.data_path+os.sep+database)
279- conn.execute("""create table if not exists song_topics (song_id integer Primary Key ASC );""")
280- conn.commit()
281- self.display.sub_output("Songtopics table created")
282- conn.execute("""alter table song_topics add column topic_id interger;""")
283- conn.commit()
284- self.display.sub_output("songtopics_topic_id added")
285+ conn.execute("""create table if not exists song_topics
286+ (song_id integer,
287+ topic_id integer);""")
288+ conn.commit()
289+ self.display.sub_output(u'songtopics table created')
290 conn.execute("""create index if not exists songtopic1 on song_topics (topic_id ASC,song_id ASC);""")
291 conn.commit()
292- self.display.sub_output("index songbook1 created")
293- conn.execute("""create index if not exists songbook2 on song_topics (song_id ASC,topic_id ASC);""")
294- conn.commit()
295- conn.close()
296- self.display.sub_output("index songbook2 created")
297- self.display.sub_output("SongTopics Completed");
298-
299- def _v1_9_0_songauthors(self, database):
300- self.display.sub_output("SongAuthors Started for "+database);
301- conn = sqlite3.connect(self.data_path+os.sep+database)
302- conn.execute("""alter table songauthors rename to authors_songs;""")
303- conn.commit()
304- conn.close()
305- self.display.sub_output("Table Renamed")
306- self.display.sub_output("SongAuthors Completed");
307-
308-
309- def _v1_9_0_songs(self, database):
310- self.display.sub_output("Songs Started for "+database);
311- conn = sqlite3.connect(self.data_path+os.sep+database)
312- conn.execute("""alter table songs add column song_book_id interger;""")
313- conn.commit()
314- self.display.sub_output("songs_song_book_id added")
315- conn.execute("""alter table songs add column verse_order varchar(128);""")
316- conn.commit()
317- self.display.sub_output("songs verse_order added")
318- conn.execute("""alter table songs add column comments text;""")
319- conn.commit()
320- self.display.sub_output("songs comments added")
321- conn.execute("""alter table songs add ccli_number varchar(64);""")
322- conn.commit()
323- self.display.sub_output("songs ccli_number added")
324- conn.execute("""alter table songs add song_number varchar(64);""")
325- conn.commit()
326- self.display.sub_output("songs song_number added")
327- conn.execute("""alter table songs add theme_name varchar(128);""")
328- conn.commit()
329- self.display.sub_output("songs theme_name added")
330- conn.execute("""alter table songs add search_title varchar(255);""")
331- conn.commit()
332- self.display.sub_output("songs search_title added")
333- conn.execute("""alter table songs add search_lyrics text;""")
334- conn.commit()
335- self.display.sub_output("songs search_lyrics added")
336-
337- conn.execute("""create index if not exists songs1 on songs (search_lyrics ASC,id ASC);""")
338- conn.commit()
339- self.display.sub_output("index songs1 created")
340- conn.execute("""create index if not exists songs2 on songs (search_title ASC,id ASC);""")
341- conn.commit()
342- conn.close()
343- self.display.sub_output("index songs2 created")
344- self.display.sub_output("Songs Completed");
345-
346-
347-
348- def _v1_9_0_songs_update(self, database):
349- self.display.sub_output("Songs Started for "+database);
350- self.db = create_engine("sqlite:///"+self.data_path+os.sep+database, encoding='utf-8' , convert_unicode=False, assert_unicode=False)
351-
352- self.db.echo = True
353- metadata.bind = self.db
354- metadata.bind.echo = False
355- Session = scoped_session(sessionmaker(autoflush=True, autocommit=False))
356- Session.configure(bind=self.db)
357- #create missing table
358- songs_topics_table.create()
359- songs = Session.query(Song).all()
360- for song in songs:
361- t=song.title.replace("&", "and")
362- t=t.replace("'", "")
363- t=t.replace(",", "")
364- t=t.replace(";", "")
365- t=t.replace(":", "")
366- t=t.replace("(", "")
367- t=t.replace(")", "")
368- t=t.replace("{", "")
369- t=t.replace("}", "")
370- t=t.replace("?", "")
371- song.search_title = t
372- t=song.lyrics.replace("&", "and")
373- t=t.replace("'", "")
374- t=t.replace(",", "")
375- t=t.replace(";", "")
376- t=t.replace(":", "")
377- t=t.replace("(", "")
378- t=t.replace(")", "")
379- t=t.replace("{", "")
380- t=t.replace("}", "")
381- t=t.replace("?", "")
382- song.search_lyrics = t
383- song.song_book_id = 0
384- Session.save_or_update(song)
385- Session.commit()
386+ self.display.sub_output(u'index songtopic1 created')
387+ conn.execute("""create index if not exists songtopic2 on song_topics (song_id ASC,topic_id ASC);""")
388+ conn.commit()
389+ conn.close()
390+ self.display.sub_output(u'index songtopic2 created')
391+ self.display.sub_output(u'SongTopics Completed')
392
393 def run_cmd(self, cmd):
394- f_i, f_o = os.popen4(cmd)
395- out = f_o.readlines()
396+ filein, fileout = os.popen4(cmd)
397+ out = fileout.readlines()
398 if len(out) > 0:
399- for o in range (0, len(out)):
400+ for o in range (0, len(out)):
401 self.display.sub_output(out[o])
402
403=== modified file 'openlpcnv.pyw' (properties changed: -x to +x)