From 2e1b671e8db49f47d69fd59ece2b58e109ec8b84 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 14 May 2026 13:49:15 +0900 Subject: [PATCH] refac --- ...update_message_and_channel_member_table.py | 121 ++++++++++-------- .../4de81c2a3af1_add_pinned_note_table.py | 61 ++++----- 2 files changed, 99 insertions(+), 83 deletions(-) diff --git a/backend/open_webui/migrations/versions/2f1211949ecc_update_message_and_channel_member_table.py b/backend/open_webui/migrations/versions/2f1211949ecc_update_message_and_channel_member_table.py index e64f8ee91f..1c0cb6da81 100644 --- a/backend/open_webui/migrations/versions/2f1211949ecc_update_message_and_channel_member_table.py +++ b/backend/open_webui/migrations/versions/2f1211949ecc_update_message_and_channel_member_table.py @@ -20,63 +20,76 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + conn = op.get_bind() + inspector = sa.inspect(conn) + # New columns to be added to channel_member table - op.add_column('channel_member', sa.Column('status', sa.Text(), nullable=True)) - op.add_column( - 'channel_member', - sa.Column( - 'is_active', - sa.Boolean(), - nullable=False, - default=True, - server_default=sa.sql.expression.true(), - ), - ) - - op.add_column( - 'channel_member', - sa.Column( - 'is_channel_muted', - sa.Boolean(), - nullable=False, - default=False, - server_default=sa.sql.expression.false(), - ), - ) - op.add_column( - 'channel_member', - sa.Column( - 'is_channel_pinned', - sa.Boolean(), - nullable=False, - default=False, - server_default=sa.sql.expression.false(), - ), - ) - - op.add_column('channel_member', sa.Column('data', sa.JSON(), nullable=True)) - op.add_column('channel_member', sa.Column('meta', sa.JSON(), nullable=True)) - - op.add_column('channel_member', sa.Column('joined_at', sa.BigInteger(), nullable=False)) - op.add_column('channel_member', sa.Column('left_at', sa.BigInteger(), nullable=True)) - - op.add_column('channel_member', sa.Column('last_read_at', sa.BigInteger(), nullable=True)) - - op.add_column('channel_member', sa.Column('updated_at', sa.BigInteger(), nullable=True)) + cm_cols = {c['name'] for c in inspector.get_columns('channel_member')} + if 'status' not in cm_cols: + op.add_column('channel_member', sa.Column('status', sa.Text(), nullable=True)) + if 'is_active' not in cm_cols: + op.add_column( + 'channel_member', + sa.Column( + 'is_active', + sa.Boolean(), + nullable=False, + default=True, + server_default=sa.sql.expression.true(), + ), + ) + if 'is_channel_muted' not in cm_cols: + op.add_column( + 'channel_member', + sa.Column( + 'is_channel_muted', + sa.Boolean(), + nullable=False, + default=False, + server_default=sa.sql.expression.false(), + ), + ) + if 'is_channel_pinned' not in cm_cols: + op.add_column( + 'channel_member', + sa.Column( + 'is_channel_pinned', + sa.Boolean(), + nullable=False, + default=False, + server_default=sa.sql.expression.false(), + ), + ) + if 'data' not in cm_cols: + op.add_column('channel_member', sa.Column('data', sa.JSON(), nullable=True)) + if 'meta' not in cm_cols: + op.add_column('channel_member', sa.Column('meta', sa.JSON(), nullable=True)) + if 'joined_at' not in cm_cols: + op.add_column('channel_member', sa.Column('joined_at', sa.BigInteger(), nullable=False)) + if 'left_at' not in cm_cols: + op.add_column('channel_member', sa.Column('left_at', sa.BigInteger(), nullable=True)) + if 'last_read_at' not in cm_cols: + op.add_column('channel_member', sa.Column('last_read_at', sa.BigInteger(), nullable=True)) + if 'updated_at' not in cm_cols: + op.add_column('channel_member', sa.Column('updated_at', sa.BigInteger(), nullable=True)) # New columns to be added to message table - op.add_column( - 'message', - sa.Column( - 'is_pinned', - sa.Boolean(), - nullable=False, - default=False, - server_default=sa.sql.expression.false(), - ), - ) - op.add_column('message', sa.Column('pinned_at', sa.BigInteger(), nullable=True)) - op.add_column('message', sa.Column('pinned_by', sa.Text(), nullable=True)) + msg_cols = {c['name'] for c in inspector.get_columns('message')} + if 'is_pinned' not in msg_cols: + op.add_column( + 'message', + sa.Column( + 'is_pinned', + sa.Boolean(), + nullable=False, + default=False, + server_default=sa.sql.expression.false(), + ), + ) + if 'pinned_at' not in msg_cols: + op.add_column('message', sa.Column('pinned_at', sa.BigInteger(), nullable=True)) + if 'pinned_by' not in msg_cols: + op.add_column('message', sa.Column('pinned_by', sa.Text(), nullable=True)) def downgrade() -> None: diff --git a/backend/open_webui/migrations/versions/4de81c2a3af1_add_pinned_note_table.py b/backend/open_webui/migrations/versions/4de81c2a3af1_add_pinned_note_table.py index eaaaaed18a..a7b019f35a 100644 --- a/backend/open_webui/migrations/versions/4de81c2a3af1_add_pinned_note_table.py +++ b/backend/open_webui/migrations/versions/4de81c2a3af1_add_pinned_note_table.py @@ -27,39 +27,42 @@ from sqlalchemy.sql import column, table def upgrade() -> None: - op.create_table( - 'pinned_note', - sa.Column('id', sa.Text(), nullable=False), - sa.Column('user_id', sa.Text(), nullable=False), - sa.Column('note_id', sa.Text(), sa.ForeignKey('note.id', ondelete='CASCADE'), nullable=False), - sa.Column('created_at', sa.BigInteger(), nullable=False), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('user_id', 'note_id', name='uq_pinned_note'), - ) - conn = op.get_bind() + inspector = sa.inspect(conn) + existing_tables = set(inspector.get_table_names()) - note_table = table('note', column('id', sa.Text), column('user_id', sa.Text), column('is_pinned', sa.Boolean)) - - pinned_note_table = table( - 'pinned_note', - column('id', sa.Text), - column('user_id', sa.Text), - column('note_id', sa.Text), - column('created_at', sa.BigInteger), - ) - - notes = conn.execute(select(note_table.c.id, note_table.c.user_id).where(note_table.c.is_pinned == True)).fetchall() - - if notes: - now = int(time.time_ns()) - conn.execute( - insert(pinned_note_table), - [{'id': str(uuid.uuid4()), 'user_id': note[1], 'note_id': note[0], 'created_at': now} for note in notes], + if 'pinned_note' not in existing_tables: + op.create_table( + 'pinned_note', + sa.Column('id', sa.Text(), nullable=False), + sa.Column('user_id', sa.Text(), nullable=False), + sa.Column('note_id', sa.Text(), sa.ForeignKey('note.id', ondelete='CASCADE'), nullable=False), + sa.Column('created_at', sa.BigInteger(), nullable=False), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('user_id', 'note_id', name='uq_pinned_note'), ) - with op.batch_alter_table('note', schema=None) as batch_op: - batch_op.drop_column('is_pinned') + note_table = table('note', column('id', sa.Text), column('user_id', sa.Text), column('is_pinned', sa.Boolean)) + + pinned_note_table = table( + 'pinned_note', + column('id', sa.Text), + column('user_id', sa.Text), + column('note_id', sa.Text), + column('created_at', sa.BigInteger), + ) + + notes = conn.execute(select(note_table.c.id, note_table.c.user_id).where(note_table.c.is_pinned == True)).fetchall() + + if notes: + now = int(time.time_ns()) + conn.execute( + insert(pinned_note_table), + [{'id': str(uuid.uuid4()), 'user_id': note[1], 'note_id': note[0], 'created_at': now} for note in notes], + ) + + with op.batch_alter_table('note', schema=None) as batch_op: + batch_op.drop_column('is_pinned') def downgrade() -> None: