SocksTheWolf / AntiScamBot

A Discord bot that shares ban lists of scammers across multiple Discord servers
https://scamguard.app/
MIT License
6 stars 3 forks source link

DB refactor for v1.5 #45

Closed user4752 closed 9 months ago

user4752 commented 10 months ago

closes https://github.com/SocksTheWolf/AntiScamBot/issues/7

A less opinionated database refactor to attempt a one to one conversion of the current raw SQL queries to an ORM library (SQLAlchemy) in order for the data returned from the database to be agnostic to the database engine selected, and allow for clarity on which fields are referenced, i.e. object._namedvalue versus object[_randomindex].

Will also allow for easier future migrations of the database should the project needs grow, or the database engine of choice change, e.g. sqlite to mysql/mariadb or postgres.

Opinions chosen are:

Visualization of the new database schema: schema

Examples of the new database objects: migrations bans servers

Recommendations / To-dos:

Current Caveats:

user4752 commented 10 months ago

Example incremental migration which adds a new table to the database

BotDatabaseSchema.py update


 class Report(Base):
    __tablename__ = "reports"

    id = Column(Integer, primary_key=True, autoincrement=True)
    discord_user_id = Column(String(32), unique=True, nullable=False)
    reporter_discord_user_id = Column(String(32), nullable=False)

BotSetup.py update

    def upgrade_version3to4(self) -> bool:
        session = Session(self.DatabaseCon)

        Base.metadata.tables[Report.__tablename__].create(self.DatabaseCon)

        appVersion = Migration(
            database_version = DatabaseMigrator.DATABASE_VERSION
        )

        session.add(appVersion)
        session.execute(text(f"PRAGMA user_version = {DatabaseMigrator.DATABASE_VERSION}"))
        session.commit()

        return True
user4752 commented 10 months ago

Example incremental migration which alters an existing table in the database

Note: This is a simplistic example, as Sqlite does NOT have an ALTER COLUMN function so enforcing NOT NULL in the schema is difficult and would require actual data migration via temp tables

BotDatabaseSchema.py update

_thread_discord_messageid is the newly added column incremental from the previous example


 class Report(Base):
    __tablename__ = "reports"

    id = Column(Integer, primary_key=True, autoincrement=True)
    discord_user_id = Column(String(32), unique=True, nullable=False)
    reporter_discord_user_id = Column(String(32), nullable=False)
    thread_discord_message_id = Column(String(32), nullable=False, default=-1)

BotSetup.py update

    def upgrade_version4to5(self) -> bool:
        session = Session(self.DatabaseCon)

        session.execute(text("ALTER TABLE reports ADD COLUMN thread_discord_message_id VARCHAR(32) NOT NULL DEFAULT -1"))

        appVersion = Migration(
            database_version = DatabaseMigrator.DATABASE_VERSION
        )

        session.add(appVersion)
        session.execute(text(f"PRAGMA user_version = {DatabaseMigrator.DATABASE_VERSION}"))
        session.commit()

        return True
SocksTheWolf commented 9 months ago

Thank you for these updates. I did have to move some code around, so I'm going to see if I can merge your changes in without you having to rewrite more. I know continuous development can be rough haha.

I'll look over and then pull locally with my test accounts for testing later!

Thank you very much for this contribution.

user4752 commented 9 months ago

Similar to the 1.0 to 1.5 release, if need be I can close, rebase, and issue a new pull request within a day or two.

SocksTheWolf commented 9 months ago

Similar to the 1.0 to 1.5 release, if need be I can close, rebase, and issue a new pull request within a day or two.

The changes are mostly minimal, specifically they are in the retry instance command handling and moving the ban embed code into the base class of the bot instead of in ScamGuard.py

So just some minor updates.

user4752 commented 9 months ago

Everything looks good from my end