Maybe; exported file contains notetype names that seems to be easy to find-and-replace to one where needed. I haven’t checked yet what would happen if I reimport it.
Trying the database way.
$ cd /sdcard/AnkiDroid
$ mkdir dbbackup
$ cp collection.anki2* dbbackup/
$ sqlite3 collection.anki2
sqlite> select id,name,mtime_secs from notetypes where name like '%plaintextimporter%' and name not like '%plaintextimporter_%' ;
1697472596652|com.ichi2.plaintextimporter|1697472596
A good candidate for the canonical notetype of this likeness.
sqlite> select count(*) from notetypes where name like '%plaintextimporter%' and id <> 1697472596652 ;
119
Number of notetypes to be remapped and deleted.
sqlite> select nt.id,count(*) n_notes from notetypes nt left join notes n on n.mid = nt.id where nt.name like '%plaintextimporter%' and nt.id <> 1697472596652 group by nt.id limit 5;
1451180286384|1932
1532351817741|35
1532352268554|1
1536153869241|53
1537957798184|30
Number of notes on some of the notetypes we marked for deletion.
sqlite> with target_note_ids as (select distinct n.id from notetypes nt left join notes n on n.mid = nt.id where nt.name like '%plaintextimporter%' and nt.id <> 1697472596652) select count(*) from target_note_ids;
7302
Number of notes we should remap.
sqlite> with target_note_ids as (select distinct n.id from notetypes nt left join notes n on n.mid = nt.id where nt.name like '%plaintextimporter%' and nt.id <> 1697472596652) update notes set mid=1697472596652 where id in (select id from target_note_ids);
sqlite> select changes();
7301
One row not updated for some reason, not sure why. Let’s ignore it.
sqlite> with target_note_ids as (select distinct n.id from notetypes nt left join notes n on n.mid = nt.id where nt.name like '%plaintextimporter%' and nt.id <> 1697472596652) select count(*) from target_note_ids;
1
Indeed only one note unremapped. After some minor debugging, looks like it’s just NULL crept in due to slightly inaccurate query (left join instead of join for target_note_ids).
sqlite> with target_note_ids as (select distinct n.id from notetypes nt join notes n on n.mid = nt.id where nt.name like '%plaintextimporter%' and nt.id <> 1697472596652) select count(*) from target_note_ids;
0
Now better.
Let’s remove unreferenced notetypes. First let’s count them.
sqlite> with used_notetype_ids as (select distinct mid from notes) select count(*) from used_notetype_ids;
21
sqlite> select count(*) from notetypes;
151
sqlite> select count(*) from notetypes where id not in (select distinct mid from notes);
130
It’s more than before because of there are other, unrelated abandoned notetypes.
sqlite> delete from notetypes where id not in (select distinct mid from notes);
Parse error: no such collation sequence: unicase
sqlite> .quit
Looks like Anki uses special things in SQLite. Published an sqlite3-loadable extension to handle this.
sqlite> .open /sdcard/AnkiDroid/collection.anki2
sqlite> .load ./libsqlite_unicase
sqlite> delete from notetypes where id not in (select distinct mid from notes);
sqlite> select changes();
130
sqlite> .quit
After loading AnkiDroid, everything seems to be OK. Database check did not found any error, now it shows “21 note types available”, with 7325 notes in com.ichi2.plaintextimporter. Studing progress, starred notes, etc. are all preserved.