Compatibility for sqlalchemy 2.0

This commit is contained in:
Ozzie Isaacs 2021-03-20 10:09:08 +01:00
parent f3d88fc746
commit 5d8d796807
4 changed files with 35 additions and 17 deletions

View File

@ -23,7 +23,11 @@ import sys
from sqlalchemy import exc, Column, String, Integer, SmallInteger, Boolean, BLOB, JSON
from sqlalchemy.exc import OperationalError
from sqlalchemy.ext.declarative import declarative_base
try:
# Compability with sqlalchemy 2.0
from sqlalchemy.orm import declarative_base
except ImportError:
from sqlalchemy.ext.declarative import declarative_base
from . import constants, cli, logger, ub
@ -66,7 +70,7 @@ class _Settings(_Base):
config_random_books = Column(Integer, default=4)
config_authors_max = Column(Integer, default=0)
config_read_column = Column(Integer, default=0)
config_title_regex = Column(String, default=u'^(A|The|An|Der|Die|Das|Den|Ein|Eine|Einen|Dem|Des|Einem|Eines)\s+')
config_title_regex = Column(String, default=r'^(A|The|An|Der|Die|Das|Den|Ein|Eine|Einen|Dem|Des|Einem|Eines)\s+')
config_mature_content_tags = Column(String, default='')
config_theme = Column(Integer, default=0)

View File

@ -30,7 +30,12 @@ from sqlalchemy import Table, Column, ForeignKey, CheckConstraint
from sqlalchemy import String, Integer, Boolean, TIMESTAMP, Float
from sqlalchemy.orm import relationship, sessionmaker, scoped_session
from sqlalchemy.orm.collections import InstrumentedList
from sqlalchemy.ext.declarative import declarative_base, DeclarativeMeta
from sqlalchemy.ext.declarative import DeclarativeMeta
try:
# Compability with sqlalchemy 2.0
from sqlalchemy.orm import declarative_base
except ImportError:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.pool import StaticPool
from sqlalchemy.sql.expression import and_, true, false, text, func, or_
from sqlalchemy.ext.associationproxy import association_proxy
@ -465,8 +470,9 @@ class CalibreDB():
isolation_level="SERIALIZABLE",
connect_args={'check_same_thread': False},
poolclass=StaticPool)
cls.engine.execute("attach database '{}' as calibre;".format(dbpath))
cls.engine.execute("attach database '{}' as app_settings;".format(app_db_path))
with cls.engine.begin() as connection:
connection.execute(text("attach database '{}' as calibre;".format(dbpath)))
connection.execute(text("attach database '{}' as app_settings;".format(app_db_path)))
conn = cls.engine.connect()
# conn.text_factory = lambda b: b.decode(errors = 'ignore') possible fix for #1302
@ -477,7 +483,7 @@ class CalibreDB():
config.db_configured = True
if not cc_classes:
cc = conn.execute("SELECT id, datatype FROM custom_columns")
cc = conn.execute(text("SELECT id, datatype FROM custom_columns"))
cc_ids = []
books_custom_column_links = {}

View File

@ -28,7 +28,11 @@ from sqlalchemy import create_engine
from sqlalchemy import Column, UniqueConstraint
from sqlalchemy import String, Integer
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base
try:
# Compability with sqlalchemy 2.0
from sqlalchemy.orm import declarative_base
except ImportError:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.exc import OperationalError, InvalidRequestError
try:

View File

@ -38,12 +38,16 @@ except ImportError:
oauth_support = True
except ImportError:
oauth_support = False
from sqlalchemy import create_engine, exc, exists, event
from sqlalchemy import create_engine, exc, exists, event, text
from sqlalchemy import Column, ForeignKey
from sqlalchemy import String, Integer, SmallInteger, Boolean, DateTime, Float, JSON
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm.attributes import flag_modified
from sqlalchemy.sql.expression import func
try:
# Compability with sqlalchemy 2.0
from sqlalchemy.orm import declarative_base
except ImportError:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import backref, relationship, sessionmaker, Session, scoped_session
from werkzeug.security import generate_password_hash
@ -484,7 +488,7 @@ def migrate_registration_table(engine, session):
def migrate_guest_password(engine, session):
try:
with engine.connect() as conn:
conn.execute("UPDATE user SET password='' where nickname = 'Guest' and password !=''")
conn.execute(text("UPDATE user SET password='' where nickname = 'Guest' and password !=''"))
session.commit()
except exc.OperationalError:
print('Settings database is not writeable. Exiting...')
@ -597,11 +601,11 @@ def migrate_Database(session):
try:
# check if one table with autoincrement is existing (should be user table)
with engine.connect() as conn:
conn.execute("SELECT COUNT(*) FROM sqlite_sequence WHERE name='user'")
conn.execute(text("SELECT COUNT(*) FROM sqlite_sequence WHERE name='user'"))
except exc.OperationalError:
# Create new table user_id and copy contents of table user into it
with engine.connect() as conn:
conn.execute("CREATE TABLE user_id (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
conn.execute(text("CREATE TABLE user_id (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"nickname VARCHAR(64),"
"email VARCHAR(120),"
"role SMALLINT,"
@ -612,14 +616,14 @@ def migrate_Database(session):
"default_language VARCHAR(3),"
"view_settings VARCHAR,"
"UNIQUE (nickname),"
"UNIQUE (email))")
conn.execute("INSERT INTO user_id(id, nickname, email, role, password, kindle_mail,locale,"
"UNIQUE (email))"))
conn.execute(text("INSERT INTO user_id(id, nickname, email, role, password, kindle_mail,locale,"
"sidebar_view, default_language, view_settings) "
"SELECT id, nickname, email, role, password, kindle_mail, locale,"
"sidebar_view, default_language FROM user")
"sidebar_view, default_language FROM user"))
# delete old user table and rename new user_id table to user:
conn.execute("DROP TABLE user")
conn.execute("ALTER TABLE user_id RENAME TO user")
conn.execute(text("DROP TABLE user"))
conn.execute(text("ALTER TABLE user_id RENAME TO user"))
session.commit()
migrate_guest_password(engine, session)