So I am not sure which way to approach this issue so I figured I'd ask for some suggestions here on the forums and get some expert opinions. Ideally I am looking for a non-hackish way to access the Plex database using Python, which does not force me to replace Python's included sqlite3.dll file with the one included with Plex, or a fresh copy from the SQLite website.
I currently have Python 2.7.6 installed on my Windows 8.1 x64 machine and when I recently attempted to run a query to update my titles to append the year at the end (like "The Usual Suspects (1995)"), I keep encountering the same error each time:
>>> import sqlite3
>>> conn = sqlite3.connect("C:/plex_temp/com.plexapp.plugins.library.db") # copied db
>>> cursor = conn.cursor()
>>> cursor.execute("""SELECT Title from metadata_items;""")
Traceback (most recent call last):
File "", line 1, in
sqlite3.DatabaseError: file is encrypted or is not a database
The copy of the database is not corrupt, there is no encryption, and it is indeed a database as the copy is accessible using SQLite GUI apps without a hitch! Apparently my installed Python 2.7.6 is what's causing the issue...
I did some googling and was able to conclude that the problem is with the default version of sqlite3.dll (v3.6.21) included with Python 2.7.6, which is far below the current version found on the SQLite download page (3.8.3.1), as well as the version included with Plex (3.8.0.2). Now after even more googling I was able to solve the problem and was able to successfully run a query by replacing the sqlite3.dll with the current version, or with the one included with Plex (a better idea, ensures compatibility), but to be honest this approach just doesn't seem right? I really don't know if this will cause any future compatibility issues down the road, and as afaik the accompanying _sqlite3.pyd was not designed for the updated version(s). Bottom line, this just seems like a really hackish way to deal with it. Having to replace/restore the sqlite3.dll each time just to access the Plex database? Is there really no other way to do this?
I figured Plex must include it's own interpreter so after digging through the Plex program folder I was able to start Plex's interpreter by running PlexScriptHost.exe from a cmd prompt. I thought this would solve the issue for sure and include Plex's sqlite3.dll version without the hackish approach, but when I attempt to import sqlite3 I receive an error stating:
>>> import sqlite3 Traceback (most recent call last): File "", line 1, in File "C:\Program Files (x86)\Plex\Plex Media Server\python27.zip\sqlite3\__init__.py", line 24, in File "C:\Program Files (x86)\Plex\Plex Media Server\python27.zip\sqlite3\dbapi2.py", line 27, in ImportError: No module named _sqlite3
ARRRGH!!! This would have been sooooooo much easier! :P
I tried a few more things like running the same command line used when PlexScriptHost.exe is launched at server startup, but naturally that produced it's own errors. I also attempted to copy Python's default _sqlite3.pyd file to Plex's program folder (as suggested in other posts for loading sqlite from an alternate location) but it also generates similar errors...and in the long run that really is no different then the original solution of copying Plex's sqlite3.dll to Python's DLLs folder.
I guess at this point I really just have two questions:
1) Is there a way to initiate PlexScriptHost.exe to allow me to import Plex's included sqlite3 version for querying..?
2) If the first approach is not possible, does anyone know of a way to force my installed python interpreter to import a different sqlite3.dll by specifying a custom location to the file, like the Plex Media Server folder?
Any help/feedback with this issue would be greatly appreciated!
P.S. Incase anyone wants to play with the SQL line I am using to update my titles, I've included it below. Note that SQL is not my strength so if anyone has suggestions on how to improve these queries, I'm all ears)
(Edit: Updated SQL query, added " (YEAR)" removal query)
-- Update Title with year "The Title (1987)" --
UPDATE metadata_items SET Title=CASE WHEN Year IS NULL OR Title LIKE ("% (" || "Year" || ")") THEN Title ELSE ("Title" || " (" || "Year" || ")") END;
– Remove Year from Title –
UPDATE metadata_items SET Title=SUBSTR(Title, 1, LENGTH(Title)-7) WHERE Title LIKE ("% (" || “Year” || “)”);