Further fixes for sqlalchemy 2.0

This commit is contained in:
Ozzie Isaacs 2023-04-12 18:56:21 +02:00
parent 592216588c
commit 6c6841f8b0
3 changed files with 35 additions and 22 deletions

View File

@ -405,9 +405,9 @@ def _encrypt_fields(session, secret_key):
session.query(exists().where(_Settings.mail_password_e)).scalar() session.query(exists().where(_Settings.mail_password_e)).scalar()
except OperationalError: except OperationalError:
with session.bind.connect() as conn: with session.bind.connect() as conn:
conn.execute("ALTER TABLE settings ADD column 'mail_password_e' String") conn.execute(text("ALTER TABLE settings ADD column 'mail_password_e' String"))
conn.execute("ALTER TABLE settings ADD column 'config_goodreads_api_secret_e' String") conn.execute(text("ALTER TABLE settings ADD column 'config_goodreads_api_secret_e' String"))
conn.execute("ALTER TABLE settings ADD column 'config_ldap_serv_password_e' String") conn.execute(text("ALTER TABLE settings ADD column 'config_ldap_serv_password_e' String"))
session.commit() session.commit()
crypter = Fernet(secret_key) crypter = Fernet(secret_key)
settings = session.query(_Settings.mail_password, _Settings.config_goodreads_api_secret, settings = session.query(_Settings.mail_password, _Settings.config_goodreads_api_secret,

View File

@ -993,7 +993,7 @@ class CalibreDB:
title = title[len(prep):] + ', ' + prep title = title[len(prep):] + ', ' + prep
return title.strip() return title.strip()
conn = conn or self.session.connection().connection.connection conn = conn or self.session.connection().connection.driver_connection
try: try:
conn.create_function("title_sort", 1, _title_sort) conn.create_function("title_sort", 1, _title_sort)
except sqliteOperationalError: except sqliteOperationalError:

View File

@ -555,8 +555,9 @@ def add_missing_tables(engine, _session):
if not engine.dialect.has_table(engine.connect(), "registration"): if not engine.dialect.has_table(engine.connect(), "registration"):
Registration.__table__.create(bind=engine) Registration.__table__.create(bind=engine)
with engine.connect() as conn: with engine.connect() as conn:
trans = conn.begin()
conn.execute("insert into registration (domain, allow) values('%.%',1)") conn.execute("insert into registration (domain, allow) values('%.%',1)")
_session.commit() trans.commit()
# migrate all settings missing in registration table # migrate all settings missing in registration table
@ -566,16 +567,18 @@ def migrate_registration_table(engine, _session):
_session.commit() _session.commit()
except exc.OperationalError: # Database is not compatible, some columns are missing except exc.OperationalError: # Database is not compatible, some columns are missing
with engine.connect() as conn: with engine.connect() as conn:
trans = conn.begin()
conn.execute(text("ALTER TABLE registration ADD column 'allow' INTEGER")) conn.execute(text("ALTER TABLE registration ADD column 'allow' INTEGER"))
conn.execute(text("update registration set 'allow' = 1")) conn.execute(text("update registration set 'allow' = 1"))
_session.commit() trans.commit()
try: try:
# Handle table exists, but no content # Handle table exists, but no content
cnt = _session.query(Registration).count() cnt = _session.query(Registration).count()
if not cnt: if not cnt:
with engine.connect() as conn: with engine.connect() as conn:
trans = conn.begin()
conn.execute(text("insert into registration (domain, allow) values('%.%',1)")) conn.execute(text("insert into registration (domain, allow) values('%.%',1)"))
_session.commit() trans.commit()
except exc.OperationalError: # Database is not writeable except exc.OperationalError: # Database is not writeable
print('Settings database is not writeable. Exiting...') print('Settings database is not writeable. Exiting...')
sys.exit(2) sys.exit(2)
@ -598,11 +601,13 @@ def migrate_shelfs(engine, _session):
_session.query(exists().where(Shelf.uuid)).scalar() _session.query(exists().where(Shelf.uuid)).scalar()
except exc.OperationalError: except exc.OperationalError:
with engine.connect() as conn: with engine.connect() as conn:
trans = conn.begin()
conn.execute(text("ALTER TABLE shelf ADD column 'uuid' STRING")) conn.execute(text("ALTER TABLE shelf ADD column 'uuid' STRING"))
conn.execute(text("ALTER TABLE shelf ADD column 'created' DATETIME")) conn.execute(text("ALTER TABLE shelf ADD column 'created' DATETIME"))
conn.execute(text("ALTER TABLE shelf ADD column 'last_modified' DATETIME")) conn.execute(text("ALTER TABLE shelf ADD column 'last_modified' DATETIME"))
conn.execute(text("ALTER TABLE book_shelf_link ADD column 'date_added' DATETIME")) conn.execute(text("ALTER TABLE book_shelf_link ADD column 'date_added' DATETIME"))
conn.execute(text("ALTER TABLE shelf ADD column 'kobo_sync' BOOLEAN DEFAULT false")) conn.execute(text("ALTER TABLE shelf ADD column 'kobo_sync' BOOLEAN DEFAULT false"))
trans.commit()
for shelf in _session.query(Shelf).all(): for shelf in _session.query(Shelf).all():
shelf.uuid = str(uuid.uuid4()) shelf.uuid = str(uuid.uuid4())
shelf.created = datetime.datetime.now() shelf.created = datetime.datetime.now()
@ -615,16 +620,16 @@ def migrate_shelfs(engine, _session):
_session.query(exists().where(Shelf.kobo_sync)).scalar() _session.query(exists().where(Shelf.kobo_sync)).scalar()
except exc.OperationalError: except exc.OperationalError:
with engine.connect() as conn: with engine.connect() as conn:
trans = conn.begin()
conn.execute(text("ALTER TABLE shelf ADD column 'kobo_sync' BOOLEAN DEFAULT false")) conn.execute(text("ALTER TABLE shelf ADD column 'kobo_sync' BOOLEAN DEFAULT false"))
_session.commit() trans.commit()
try: try:
_session.query(exists().where(BookShelf.order)).scalar() _session.query(exists().where(BookShelf.order)).scalar()
except exc.OperationalError: # Database is not compatible, some columns are missing except exc.OperationalError: # Database is not compatible, some columns are missing
with engine.connect() as conn: with engine.connect() as conn:
trans = conn.begin()
conn.execute(text("ALTER TABLE book_shelf_link ADD column 'order' INTEGER DEFAULT 1")) conn.execute(text("ALTER TABLE book_shelf_link ADD column 'order' INTEGER DEFAULT 1"))
_session.commit() trans.commit()
def migrate_readBook(engine, _session): def migrate_readBook(engine, _session):
@ -632,12 +637,13 @@ def migrate_readBook(engine, _session):
_session.query(exists().where(ReadBook.read_status)).scalar() _session.query(exists().where(ReadBook.read_status)).scalar()
except exc.OperationalError: except exc.OperationalError:
with engine.connect() as conn: with engine.connect() as conn:
trans = conn.begin()
conn.execute(text("ALTER TABLE book_read_link ADD column 'read_status' INTEGER DEFAULT 0")) conn.execute(text("ALTER TABLE book_read_link ADD column 'read_status' INTEGER DEFAULT 0"))
conn.execute(text("UPDATE book_read_link SET 'read_status' = 1 WHERE is_read")) conn.execute(text("UPDATE book_read_link SET 'read_status' = 1 WHERE is_read"))
conn.execute(text("ALTER TABLE book_read_link ADD column 'last_modified' DATETIME")) conn.execute(text("ALTER TABLE book_read_link ADD column 'last_modified' DATETIME"))
conn.execute(text("ALTER TABLE book_read_link ADD column 'last_time_started_reading' DATETIME")) conn.execute(text("ALTER TABLE book_read_link ADD column 'last_time_started_reading' DATETIME"))
conn.execute(text("ALTER TABLE book_read_link ADD column 'times_started_reading' INTEGER DEFAULT 0")) conn.execute(text("ALTER TABLE book_read_link ADD column 'times_started_reading' INTEGER DEFAULT 0"))
_session.commit() trans.commit()
test = _session.query(ReadBook).filter(ReadBook.last_modified == None).all() test = _session.query(ReadBook).filter(ReadBook.last_modified == None).all()
for book in test: for book in test:
book.last_modified = datetime.datetime.utcnow() book.last_modified = datetime.datetime.utcnow()
@ -650,9 +656,10 @@ def migrate_remoteAuthToken(engine, _session):
_session.commit() _session.commit()
except exc.OperationalError: # Database is not compatible, some columns are missing except exc.OperationalError: # Database is not compatible, some columns are missing
with engine.connect() as conn: with engine.connect() as conn:
trans = conn.begin()
conn.execute(text("ALTER TABLE remote_auth_token ADD column 'token_type' INTEGER DEFAULT 0")) conn.execute(text("ALTER TABLE remote_auth_token ADD column 'token_type' INTEGER DEFAULT 0"))
conn.execute(text("update remote_auth_token set 'token_type' = 0")) conn.execute(text("update remote_auth_token set 'token_type' = 0"))
_session.commit() trans.commit()
# Migrate database to current version, has to be updated after every database change. Currently migration from # Migrate database to current version, has to be updated after every database change. Currently migration from
# everywhere to current should work. Migration is done by checking if relevant columns are existing, and than adding # everywhere to current should work. Migration is done by checking if relevant columns are existing, and than adding
@ -669,16 +676,19 @@ def migrate_Database(_session):
_session.query(exists().where(User.sidebar_view)).scalar() _session.query(exists().where(User.sidebar_view)).scalar()
except exc.OperationalError: # Database is not compatible, some columns are missing except exc.OperationalError: # Database is not compatible, some columns are missing
with engine.connect() as conn: with engine.connect() as conn:
trans = conn.begin()
conn.execute(text("ALTER TABLE user ADD column `sidebar_view` Integer DEFAULT 1")) conn.execute(text("ALTER TABLE user ADD column `sidebar_view` Integer DEFAULT 1"))
_session.commit() trans.commit()
create = True create = True
try: try:
if create: if create:
with engine.connect() as conn: with engine.connect() as conn:
trans = conn.begin()
conn.execute(text("SELECT language_books FROM user")) conn.execute(text("SELECT language_books FROM user"))
_session.commit() trans.commit()
except exc.OperationalError: except exc.OperationalError:
with engine.connect() as conn: with engine.connect() as conn:
trans = conn.begin()
conn.execute(text("UPDATE user SET 'sidebar_view' = (random_books* :side_random + language_books * :side_lang " conn.execute(text("UPDATE user SET 'sidebar_view' = (random_books* :side_random + language_books * :side_lang "
"+ series_books * :side_series + category_books * :side_category + hot_books * " "+ series_books * :side_series + category_books * :side_category + hot_books * "
":side_hot + :side_autor + :detail_random)"), ":side_hot + :side_autor + :detail_random)"),
@ -686,35 +696,38 @@ def migrate_Database(_session):
'side_series': constants.SIDEBAR_SERIES, 'side_category': constants.SIDEBAR_CATEGORY, 'side_series': constants.SIDEBAR_SERIES, 'side_category': constants.SIDEBAR_CATEGORY,
'side_hot': constants.SIDEBAR_HOT, 'side_autor': constants.SIDEBAR_AUTHOR, 'side_hot': constants.SIDEBAR_HOT, 'side_autor': constants.SIDEBAR_AUTHOR,
'detail_random': constants.DETAIL_RANDOM}) 'detail_random': constants.DETAIL_RANDOM})
_session.commit() trans.commit()
try: try:
_session.query(exists().where(User.denied_tags)).scalar() _session.query(exists().where(User.denied_tags)).scalar()
except exc.OperationalError: # Database is not compatible, some columns are missing except exc.OperationalError: # Database is not compatible, some columns are missing
with engine.connect() as conn: with engine.connect() as conn:
trans = conn.begin()
conn.execute(text("ALTER TABLE user ADD column `denied_tags` String DEFAULT ''")) conn.execute(text("ALTER TABLE user ADD column `denied_tags` String DEFAULT ''"))
conn.execute(text("ALTER TABLE user ADD column `allowed_tags` String DEFAULT ''")) conn.execute(text("ALTER TABLE user ADD column `allowed_tags` String DEFAULT ''"))
conn.execute(text("ALTER TABLE user ADD column `denied_column_value` String DEFAULT ''")) conn.execute(text("ALTER TABLE user ADD column `denied_column_value` String DEFAULT ''"))
conn.execute(text("ALTER TABLE user ADD column `allowed_column_value` String DEFAULT ''")) conn.execute(text("ALTER TABLE user ADD column `allowed_column_value` String DEFAULT ''"))
_session.commit() trans.commit()
try: try:
_session.query(exists().where(User.view_settings)).scalar() _session.query(exists().where(User.view_settings)).scalar()
except exc.OperationalError: except exc.OperationalError:
with engine.connect() as conn: with engine.connect() as conn:
trans = conn.begin()
conn.execute(text("ALTER TABLE user ADD column `view_settings` VARCHAR(10) DEFAULT '{}'")) conn.execute(text("ALTER TABLE user ADD column `view_settings` VARCHAR(10) DEFAULT '{}'"))
_session.commit() trans.commit()
try: try:
_session.query(exists().where(User.kobo_only_shelves_sync)).scalar() _session.query(exists().where(User.kobo_only_shelves_sync)).scalar()
except exc.OperationalError: except exc.OperationalError:
with engine.connect() as conn: with engine.connect() as conn:
conn.execute("ALTER TABLE user ADD column `kobo_only_shelves_sync` SMALLINT DEFAULT 0") trans = conn.begin()
_session.commit() conn.execute(text("ALTER TABLE user ADD column `kobo_only_shelves_sync` SMALLINT DEFAULT 0"))
trans.commit()
try: try:
# check if name is in User table instead of nickname # check if name is in User table instead of nickname
_session.query(exists().where(User.name)).scalar() _session.query(exists().where(User.name)).scalar()
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:
trans = conn.begin()
conn.execute(text("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,"
"name VARCHAR(64)," "name VARCHAR(64),"
"email VARCHAR(120)," "email VARCHAR(120),"
@ -741,7 +754,7 @@ def migrate_Database(_session):
# 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(text("DROP TABLE user")) conn.execute(text("DROP TABLE user"))
conn.execute(text("ALTER TABLE user_id RENAME TO user")) conn.execute(text("ALTER TABLE user_id RENAME TO user"))
_session.commit() trans.commit()
if _session.query(User).filter(User.role.op('&')(constants.ROLE_ANONYMOUS) == constants.ROLE_ANONYMOUS).first() \ if _session.query(User).filter(User.role.op('&')(constants.ROLE_ANONYMOUS) == constants.ROLE_ANONYMOUS).first() \
is None: is None:
create_anonymous_user(_session) create_anonymous_user(_session)