zothero: malformed database schema error

I am experiencing this error from zothero.

12:31:39 workflow.py:2114 ERROR    malformed database schema (autoexport_setting_insert) - trigger autoexport_setting_insert cannot reference objects in database betterbibtex
Traceback (most recent call last):
  File "/Users/jacob/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.3536781B-080F-473B-B07D-8AD609D0784F/lib/workflow/workflow.py", line 2107, in run
    func(self)
  File "/Users/jacob/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.3536781B-080F-473B-B07D-8AD609D0784F/zh.py", line 734, in main
    return do_search(query)
           ^^^^^^^^^^^^^^^^
  File "/Users/jacob/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.3536781B-080F-473B-B07D-8AD609D0784F/zh.py", line 130, in do_search
    if app.stale and not running:
       ^^^^^^^^^
  File "/Users/jacob/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.3536781B-080F-473B-B07D-8AD609D0784F/lib/zothero/core.py", line 166, in stale
    if self.index.empty:
       ^^^^^^^^^^
  File "/Users/jacob/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.3536781B-080F-473B-B07D-8AD609D0784F/lib/zothero/core.py", line 159, in index
    self._index.update(self.zotero)
  File "/Users/jacob/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.3536781B-080F-473B-B07D-8AD609D0784F/lib/zothero/index.py", line 277, in update
    if not self._update(zot, force):
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jacob/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.3536781B-080F-473B-B07D-8AD609D0784F/lib/zothero/index.py", line 325, in _update
    for e in it:
  File "/Users/jacob/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.3536781B-080F-473B-B07D-8AD609D0784F/lib/zothero/zotero.py", line 292, in all_entries
    yield self._load_entry(row)
          ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jacob/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.3536781B-080F-473B-B07D-8AD609D0784F/lib/zothero/zotero.py", line 344, in _load_entry
    e.citekey = self.bbt.citekey('{}_{}'.format(e.library, e.key))
                ^^^^^^^^
  File "/Users/jacob/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.3536781B-080F-473B-B07D-8AD609D0784F/lib/zothero/zotero.py", line 214, in bbt
    self._bbt = BetterBibTex(self.bibpath_copy)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jacob/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.3536781B-080F-473B-B07D-8AD609D0784F/lib/zothero/betterbibtex.py", line 54, in __init__
    row = conn.execute(SQL).fetchone()
          ^^^^^^^^^^^^^^^^^
sqlite3.DatabaseError: malformed database schema (autoexport_setting_insert) - trigger autoexport_setting_insert cannot reference objects in database betterbibtex
12:31:39 workflow.py:2116 INFO     for assistance, see: https://github.com/giovannicoppola/zothero/issues

Reload Zotero Data can not fix this. I suspect the cause is that it is incompatible with the last version of betterbibtex, which is 6.7.128 as of today.

About this issue

  • Original URL
  • State: closed
  • Created 8 months ago
  • Comments: 28 (7 by maintainers)

Most upvoted comments

Untested but this should work:

diff --git a/src/lib/zothero/betterbibtex.py b/src/lib/zothero/betterbibtex.py
index df9f23a..eee83ec 100644
--- a/src/lib/zothero/betterbibtex.py
+++ b/src/lib/zothero/betterbibtex.py
@@ -16,9 +16,6 @@ from .util import timed
 log = logging.getLogger(__name__)
 
 
-SQL = "SELECT data FROM `better-bibtex` WHERE name = 'better-bibtex.citekey';"
-
-
 class BetterBibTex(object):
     """Read citkeys from BetterBibTex database.
 
@@ -47,15 +44,14 @@ class BetterBibTex(object):
             
             return
 
-        conn = sqlite3.connect(dbpath)
+        conn = sqlite3.connect(':memory:')
+        conn.execute('ATTACH DATABASE ? AS betterbibtex', dbpath)
         
         with timed('load Better Bibtex data'):
             
-            row = conn.execute(SQL).fetchone()
-            data = json.loads(row[0])['data']
             self._refkeys = {
-                str(ck['libraryID']) + '_' + ck['itemKey']: ck['citekey']
-                for ck in data
+                str(ck['libraryID']) + '_' + ck['itemKey']: ck['citationKey']
+                for c in conn.execute('select * from betterbibtex.citationkey')
             }
         self.exists = True
 

You issue

SELECT COUNT(*) FROM betterbibtex.sqlite_master WHERE type='table' AND name = 'citationkey'

If that returns 1, you have the new database (get the keys from betterbibtex.citationkey), if it returns 0 you have the old database (get the keys from betterbibtex."better-bibtex").

Thanks! I will give it a try.

Untested but this should work:

diff --git a/src/lib/zothero/betterbibtex.py b/src/lib/zothero/betterbibtex.py
index df9f23a..eee83ec 100644
--- a/src/lib/zothero/betterbibtex.py
+++ b/src/lib/zothero/betterbibtex.py
@@ -16,9 +16,6 @@ from .util import timed
 log = logging.getLogger(__name__)
 
 
-SQL = "SELECT data FROM `better-bibtex` WHERE name = 'better-bibtex.citekey';"
-
-
 class BetterBibTex(object):
     """Read citkeys from BetterBibTex database.
 
@@ -47,15 +44,14 @@ class BetterBibTex(object):
             
             return
 
-        conn = sqlite3.connect(dbpath)
+        conn = sqlite3.connect(':memory:')
+        conn.execute('ATTACH DATABASE ? AS betterbibtex', dbpath)
         
         with timed('load Better Bibtex data'):
             
-            row = conn.execute(SQL).fetchone()
-            data = json.loads(row[0])['data']
             self._refkeys = {
-                str(ck['libraryID']) + '_' + ck['itemKey']: ck['citekey']
-                for ck in data
+                str(ck['libraryID']) + '_' + ck['itemKey']: ck['citationKey']
+                for c in conn.execute('select * from betterbibtex.citationkey')
             }
         self.exists = True
 

Thank you so much for the solution!

I have to do a bit adjustments to make it work:

  1. Add an additional conn.row_factory = sqlite3.Row to access the data in row using str as indices. Iterating conn.execute(‘select …’) would return tuples otherwise.
  2. Wrap dbpath with parentheses and a comma (like (dbpath, )) to expand the argument correctly into the sql command.
  3. Use for ck in conn.execute('select * from betterbibtex.citationkey') instead of for c in .... This might be a typo.

The whole __init__ method now looks like this:

    def __init__(self, datadir):
        """Load Better Bibtex database from Zotero data directory.

        Args:
            datadir (unicode, optional): Zotero's data directory.

        Raises:
            RuntimeError: Raised if Better Bibtex database doesn't exist.

        """
        
        self._refkeys = {}
        self.exists = False
        #dbpath = os.path.join(datadir, 'better-bibtex.sqlite')
        dbpath = datadir
        
        if not os.path.exists(dbpath):
            
            return

        conn = sqlite3.connect(':memory:')
        conn.row_factory = sqlite3.Row
        conn.execute('ATTACH DATABASE ? AS betterbibtex', (dbpath, ))
        
        with timed('load Better Bibtex data'):
            
            # for ck in conn.execute('select * from betterbibtex.citationkey'):
            #     print(ck)
            self._refkeys = {
                str(ck['libraryID']) + '_' + ck['itemKey']: ck['citationKey']
                for ck in conn.execute('select * from betterbibtex.citationkey')
            }
        self.exists = True

Now everything works like a charm.

Hope this can help you guys.

No, those are targeted changes, you can’t replace the whole file. The author of this program will have to get involved.

Hi, all - just FYI, if you haven’t updated to Zotero 7, it’s possible to just downgrade to BBT (I used 6.7.71 via Zotero tools/addons/install add on from file). There’s a “corrupt database” error message, but reloading Zotero data via zotconf seems to have resolved all issues with the workflow for now.

Which Zotero will undo within 48 hours by finding a newer BBT and installing that automatically. Please apply the patch to Zothero.

The database schema for auto-exports did change, and another change is slated for the citation key database.