Skip to content

Commit c3e46c0

Browse files
authored
Merge pull request #811 from TotallyNotRobots/renovate/sqlalchemy-2.x
chore(deps): update dependency sqlalchemy to v2
2 parents 715c6dc + 9b69dbc commit c3e46c0

24 files changed

Lines changed: 376 additions & 234 deletions

alembic/versions/18971030c3e0_update_quote_table_to_use_booleans.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def upgrade() -> None:
5656
sa.PrimaryKeyConstraint("chan", "nick", "msg"),
5757
)
5858
op.bulk_insert(
59-
new_table.name,
59+
new_table,
6060
[
6161
{
6262
"chan": row.chan,
@@ -82,7 +82,7 @@ def downgrade() -> None:
8282
sa.column("add_nick", sa.String(25)),
8383
sa.column("msg", sa.String(500)),
8484
sa.column("time", sa.REAL),
85-
sa.column("deleted", sa.Boolean, default=False),
85+
sa.column("deleted", sa.Boolean),
8686
)
8787

8888
if inspector.has_table(new_table.name):
@@ -102,7 +102,7 @@ def downgrade() -> None:
102102
)
103103

104104
op.bulk_insert(
105-
old_table.name,
105+
old_table,
106106
[
107107
{
108108
"chan": row.chan,
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""Sync nullables after migration
2+
3+
Revision ID: 7ddf6215d3dd
4+
Revises: e31beb6a9203
5+
Create Date: 2025-11-18 17:42:39.879061
6+
7+
"""
8+
9+
from __future__ import annotations
10+
11+
from typing import TYPE_CHECKING
12+
13+
import sqlalchemy as sa
14+
from alembic import op
15+
16+
if TYPE_CHECKING:
17+
from collections.abc import Sequence
18+
19+
# revision identifiers, used by Alembic.
20+
revision: str = "7ddf6215d3dd"
21+
down_revision: str | Sequence[str] | None = "e31beb6a9203"
22+
branch_labels: str | Sequence[str] | None = None
23+
depends_on: str | Sequence[str] | None = None
24+
25+
26+
def upgrade() -> None:
27+
"""Upgrade schema."""
28+
# ### commands auto generated by Alembic - please adjust! ###
29+
with op.batch_alter_table("tell_messages") as batch:
30+
batch.alter_column(
31+
"is_read", existing_type=sa.BOOLEAN(), nullable=False
32+
)
33+
# ### end Alembic commands ###
34+
35+
36+
def downgrade() -> None:
37+
"""Downgrade schema."""
38+
# ### commands auto generated by Alembic - please adjust! ###
39+
with op.batch_alter_table("tell_messages") as batch:
40+
batch.alter_column("is_read", existing_type=sa.BOOLEAN(), nullable=True)
41+
# ### end Alembic commands ###

alembic/versions/e31beb6a9203_add_msg_id_to_tells_table.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ def upgrade() -> None:
4040
)
4141
if inspector.has_table(old_table.name):
4242
with Session(bind=op.get_bind()) as session:
43-
old_tells = session.execute(sa.select(old_table)).fetchall()
43+
old_tells = (
44+
session.execute(sa.select(old_table)).mappings().fetchall()
45+
)
4446

4547
op.drop_table("tell_messages", if_exists=True)
4648
new_table = op.create_table(
@@ -81,7 +83,7 @@ def downgrade() -> None:
8183
inspector = sa.inspect(op.get_bind())
8284
new_table = sa.table(
8385
"tell_messages",
84-
sa.column("msg_id", sa.Integer, autoincrement=True, primary_key=True),
86+
sa.column("msg_id", sa.Integer),
8587
sa.column("conn", sa.String),
8688
sa.column("sender", sa.String),
8789
sa.column("target", sa.String),
@@ -93,7 +95,9 @@ def downgrade() -> None:
9395

9496
if inspector.has_table(new_table.name):
9597
with Session(bind=op.get_bind()) as session:
96-
new_tells = session.execute(sa.select(new_table)).fetchall()
98+
new_tells = (
99+
session.execute(sa.select(new_table)).mappings().fetchall()
100+
)
97101

98102
op.drop_table("tells", if_exists=True)
99103
old_table = op.create_table(

cloudbot/bot.py

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@
2828
from cloudbot.util.mapping import KeyFoldDict
2929

3030
if TYPE_CHECKING:
31-
from sqlalchemy import Table
3231
from sqlalchemy.engine import Engine
33-
from sqlalchemy.orm import Session
3432

3533
from cloudbot.client import Client
3634

@@ -200,8 +198,8 @@ def __init__(
200198
max_workers=self.config.get("thread_count")
201199
)
202200

203-
self.old_db = self.config.get("old_database")
204-
self.do_db_migrate = self.config.get("migrate_db")
201+
self.old_db: str | None = self.config.get("old_database")
202+
self.do_db_migrate: bool = self.config.get("migrate_db", False)
205203

206204
# set values for reloading
207205
reloading_conf = self.config.get("reloading", {})
@@ -354,7 +352,7 @@ async def _init_routine(self) -> None:
354352
await self.plugin_manager.load_all(self.plugin_dir)
355353

356354
if self.old_db and self.do_db_migrate:
357-
self.migrate_db()
355+
self.migrate_db(old_db_url=self.old_db)
358356
if self.stopped_future:
359357
self.stopped_future.set_result(False)
360358

@@ -548,24 +546,33 @@ async def reload_config(self) -> None:
548546

549547
await asyncio.gather(*tasks)
550548

551-
def migrate_db(self) -> None:
549+
def migrate_db(self, *, old_db_url: str) -> None:
552550
logger.info("Migrating database")
553-
engine: Engine = create_engine(self.old_db, future=True)
554-
old_session: Session = scoped_session(sessionmaker(bind=engine))()
555-
new_session: Session = database.Session()
556-
table: Table
557-
inspector = sa_inspect(engine)
558-
for table in database.metadata.tables.values():
559-
logger.info("Migrating table %s", table.name)
560-
if not inspector.has_table(table.name):
561-
continue
551+
engine: Engine = create_engine(old_db_url, future=True)
552+
with (
553+
scoped_session(
554+
sessionmaker(bind=engine, future=True)
555+
)() as old_session,
556+
database.Session() as new_session,
557+
):
558+
inspector = sa_inspect(engine)
559+
for table in database.metadata.tables.values():
560+
logger.info("Migrating table %s", table.name)
561+
if not inspector.has_table(table.name):
562+
continue
562563

563-
old_data = old_session.execute(table.select()).mappings().fetchall()
564-
if not old_data:
565-
continue
564+
old_data = (
565+
old_session.execute(table.select()).mappings().fetchall()
566+
)
567+
if not old_data:
568+
continue
569+
570+
table.create(bind=self.db_engine, checkfirst=True)
571+
new_session.execute(
572+
table.insert(), [dict(row) for row in old_data]
573+
)
574+
new_session.commit()
575+
old_session.execute(table.delete())
576+
old_session.commit()
566577

567-
table.create(bind=self.db_engine, checkfirst=True)
568-
new_session.execute(table.insert(), [dict(row) for row in old_data])
569-
new_session.commit()
570-
old_session.execute(table.delete())
571-
old_session.commit()
578+
engine.dispose()

cloudbot/event.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
if TYPE_CHECKING:
1515
from collections.abc import Iterator
1616

17+
import sqlalchemy.orm as sa_orm
18+
1719
logger = logging.getLogger("cloudbot")
1820

1921

@@ -79,7 +81,7 @@ def __init__(
7981
should be removed from the front.
8082
:param irc_ctcp_text: CTCP text if this message is a CTCP command
8183
"""
82-
self.db = None
84+
self.db: sa_orm.Session | None = None
8385
self.db_executor: concurrent.futures.Executor | None = None
8486
self.bot = bot
8587
self.conn = conn

0 commit comments

Comments
 (0)