This commit is contained in:
Timothy Jaeryang Baek
2026-05-14 13:49:15 +09:00
parent db2b3d7fd8
commit 2e1b671e8d
2 changed files with 99 additions and 83 deletions
@@ -20,63 +20,76 @@ depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None: def upgrade() -> None:
conn = op.get_bind()
inspector = sa.inspect(conn)
# New columns to be added to channel_member table # New columns to be added to channel_member table
op.add_column('channel_member', sa.Column('status', sa.Text(), nullable=True)) cm_cols = {c['name'] for c in inspector.get_columns('channel_member')}
op.add_column( if 'status' not in cm_cols:
'channel_member', op.add_column('channel_member', sa.Column('status', sa.Text(), nullable=True))
sa.Column( if 'is_active' not in cm_cols:
'is_active', op.add_column(
sa.Boolean(), 'channel_member',
nullable=False, sa.Column(
default=True, 'is_active',
server_default=sa.sql.expression.true(), sa.Boolean(),
), nullable=False,
) default=True,
server_default=sa.sql.expression.true(),
op.add_column( ),
'channel_member', )
sa.Column( if 'is_channel_muted' not in cm_cols:
'is_channel_muted', op.add_column(
sa.Boolean(), 'channel_member',
nullable=False, sa.Column(
default=False, 'is_channel_muted',
server_default=sa.sql.expression.false(), sa.Boolean(),
), nullable=False,
) default=False,
op.add_column( server_default=sa.sql.expression.false(),
'channel_member', ),
sa.Column( )
'is_channel_pinned', if 'is_channel_pinned' not in cm_cols:
sa.Boolean(), op.add_column(
nullable=False, 'channel_member',
default=False, sa.Column(
server_default=sa.sql.expression.false(), 'is_channel_pinned',
), sa.Boolean(),
) nullable=False,
default=False,
op.add_column('channel_member', sa.Column('data', sa.JSON(), nullable=True)) server_default=sa.sql.expression.false(),
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)) if 'data' not in cm_cols:
op.add_column('channel_member', sa.Column('left_at', sa.BigInteger(), nullable=True)) 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('last_read_at', sa.BigInteger(), nullable=True)) 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('updated_at', sa.BigInteger(), nullable=True)) 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 # New columns to be added to message table
op.add_column( msg_cols = {c['name'] for c in inspector.get_columns('message')}
'message', if 'is_pinned' not in msg_cols:
sa.Column( op.add_column(
'is_pinned', 'message',
sa.Boolean(), sa.Column(
nullable=False, 'is_pinned',
default=False, sa.Boolean(),
server_default=sa.sql.expression.false(), 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)) )
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: def downgrade() -> None:
@@ -27,39 +27,42 @@ from sqlalchemy.sql import column, table
def upgrade() -> None: 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() 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)) if 'pinned_note' not in existing_tables:
op.create_table(
pinned_note_table = table( 'pinned_note',
'pinned_note', sa.Column('id', sa.Text(), nullable=False),
column('id', sa.Text), sa.Column('user_id', sa.Text(), nullable=False),
column('user_id', sa.Text), sa.Column('note_id', sa.Text(), sa.ForeignKey('note.id', ondelete='CASCADE'), nullable=False),
column('note_id', sa.Text), sa.Column('created_at', sa.BigInteger(), nullable=False),
column('created_at', sa.BigInteger), sa.PrimaryKeyConstraint('id'),
) sa.UniqueConstraint('user_id', 'note_id', name='uq_pinned_note'),
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: note_table = table('note', column('id', sa.Text), column('user_id', sa.Text), column('is_pinned', sa.Boolean))
batch_op.drop_column('is_pinned')
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: def downgrade() -> None: