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 import exc, Column, String, Integer, SmallInteger, Boolean, BLOB, JSON
from sqlalchemy.exc import OperationalError 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 from . import constants, cli, logger, ub
@ -66,7 +70,7 @@ class _Settings(_Base):
config_random_books = Column(Integer, default=4) config_random_books = Column(Integer, default=4)
config_authors_max = Column(Integer, default=0) config_authors_max = Column(Integer, default=0)
config_read_column = 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_mature_content_tags = Column(String, default='')
config_theme = Column(Integer, default=0) 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 import String, Integer, Boolean, TIMESTAMP, Float
from sqlalchemy.orm import relationship, sessionmaker, scoped_session from sqlalchemy.orm import relationship, sessionmaker, scoped_session
from sqlalchemy.orm.collections import InstrumentedList 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.pool import StaticPool
from sqlalchemy.sql.expression import and_, true, false, text, func, or_ from sqlalchemy.sql.expression import and_, true, false, text, func, or_
from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.ext.associationproxy import association_proxy
@ -465,8 +470,9 @@ class CalibreDB():
isolation_level="SERIALIZABLE", isolation_level="SERIALIZABLE",
connect_args={'check_same_thread': False}, connect_args={'check_same_thread': False},
poolclass=StaticPool) poolclass=StaticPool)
cls.engine.execute("attach database '{}' as calibre;".format(dbpath)) with cls.engine.begin() as connection:
cls.engine.execute("attach database '{}' as app_settings;".format(app_db_path)) 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 = cls.engine.connect()
# conn.text_factory = lambda b: b.decode(errors = 'ignore') possible fix for #1302 # conn.text_factory = lambda b: b.decode(errors = 'ignore') possible fix for #1302
@ -477,7 +483,7 @@ class CalibreDB():
config.db_configured = True config.db_configured = True
if not cc_classes: 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 = [] cc_ids = []
books_custom_column_links = {} books_custom_column_links = {}

View File

@ -28,7 +28,11 @@ from sqlalchemy import create_engine
from sqlalchemy import Column, UniqueConstraint from sqlalchemy import Column, UniqueConstraint
from sqlalchemy import String, Integer from sqlalchemy import String, Integer
from sqlalchemy.orm import sessionmaker, scoped_session 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 from sqlalchemy.exc import OperationalError, InvalidRequestError
try: try:

View File

@ -38,12 +38,16 @@ except ImportError:
oauth_support = True oauth_support = True
except ImportError: except ImportError:
oauth_support = False 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 Column, ForeignKey
from sqlalchemy import String, Integer, SmallInteger, Boolean, DateTime, Float, JSON 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.orm.attributes import flag_modified
from sqlalchemy.sql.expression import func 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 sqlalchemy.orm import backref, relationship, sessionmaker, Session, scoped_session
from werkzeug.security import generate_password_hash from werkzeug.security import generate_password_hash
@ -484,7 +488,7 @@ def migrate_registration_table(engine, session):
def migrate_guest_password(engine, session): def migrate_guest_password(engine, session):
try: try:
with engine.connect() as conn: 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() session.commit()
except exc.OperationalError: except exc.OperationalError:
print('Settings database is not writeable. Exiting...') print('Settings database is not writeable. Exiting...')
@ -597,11 +601,11 @@ def migrate_Database(session):
try: try:
# check if one table with autoincrement is existing (should be user table) # check if one table with autoincrement is existing (should be user table)
with engine.connect() as conn: 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: except exc.OperationalError:
# Create new table user_id and copy contents of table user into it # Create new table user_id and copy contents of table user into it
with engine.connect() as conn: 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)," "nickname VARCHAR(64),"
"email VARCHAR(120)," "email VARCHAR(120),"
"role SMALLINT," "role SMALLINT,"
@ -612,14 +616,14 @@ def migrate_Database(session):
"default_language VARCHAR(3)," "default_language VARCHAR(3),"
"view_settings VARCHAR," "view_settings VARCHAR,"
"UNIQUE (nickname)," "UNIQUE (nickname),"
"UNIQUE (email))") "UNIQUE (email))"))
conn.execute("INSERT INTO user_id(id, nickname, email, role, password, kindle_mail,locale," conn.execute(text("INSERT INTO user_id(id, nickname, email, role, password, kindle_mail,locale,"
"sidebar_view, default_language, view_settings) " "sidebar_view, default_language, view_settings) "
"SELECT id, nickname, email, role, password, kindle_mail, locale," "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: # delete old user table and rename new user_id table to user:
conn.execute("DROP TABLE user") conn.execute(text("DROP TABLE user"))
conn.execute("ALTER TABLE user_id RENAME TO user") conn.execute(text("ALTER TABLE user_id RENAME TO user"))
session.commit() session.commit()
migrate_guest_password(engine, session) migrate_guest_password(engine, session)