1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
"""header_matches
Revision ID: 42756496720
Revises: 2bb9b382198
Create Date: 2015-09-11 10:11:38.310315
"""
import sqlalchemy as sa
from alembic import op
from mailman.database.helpers import exists_in_db, is_sqlite
from mailman.database.types import SAUnicode
# Revision identifiers, used by Alembic.
revision = '42756496720'
down_revision = '2bb9b382198'
def upgrade():
# Create the new table
header_match_table = op.create_table(
'headermatch',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('mailing_list_id', sa.Integer(), nullable=True),
sa.Column('header', SAUnicode(), nullable=False),
sa.Column('pattern', SAUnicode(), nullable=False),
sa.Column('chain', SAUnicode(), nullable=True),
sa.ForeignKeyConstraint(['mailing_list_id'], ['mailinglist.id'], ),
sa.PrimaryKeyConstraint('id')
)
# Now migrate the data. It can't be offline because we need to read the
# pickles.
connection = op.get_bind()
# Don't import the table definition from the models, it may break this
# migration when the model is updated in the future (see the Alembic doc).
mlist_table = sa.sql.table(
'mailinglist',
sa.sql.column('id', sa.Integer),
sa.sql.column('header_matches', sa.PickleType)
)
for mlist_id, old_matches in connection.execute(mlist_table.select()):
for old_match in old_matches:
connection.execute(header_match_table.insert().values(
mailing_list_id=mlist_id,
header=old_match[0],
pattern=old_match[1],
chain=None
))
# Now that data is migrated, drop the old column (except on SQLite which
# does not support this)
if not is_sqlite(connection):
op.drop_column('mailinglist', 'header_matches')
def downgrade():
if not exists_in_db(op.get_bind(), 'mailinglist', 'header_matches'):
# SQLite will not have deleted the former column, since it does not
# support column deletion.
op.add_column(
'mailinglist',
sa.Column('header_matches', sa.PickleType, nullable=True))
# Now migrate the data. It can't be offline because we need to read the
# pickles.
connection = op.get_bind()
# Don't import the table definition from the models, it may break this
# migration when the model is updated in the future (see the Alembic doc).
mlist_table = sa.sql.table(
'mailinglist',
sa.sql.column('id', sa.Integer),
sa.sql.column('header_matches', sa.PickleType)
)
header_match_table = sa.sql.table(
'headermatch',
sa.sql.column('mailing_list_id', sa.Integer),
sa.sql.column('header', SAUnicode),
sa.sql.column('pattern', SAUnicode),
)
for mlist_id, header, pattern in connection.execute(
header_match_table.select()).fetchall():
mlist = connection.execute(mlist_table.select().where(
mlist_table.c.id == mlist_id)).fetchone()
header_matches = mlist['header_matches']
if not header_matches:
header_matches = []
header_matches.append((header, pattern))
connection.execute(mlist_table.update().where(
mlist_table.c.id == mlist_id).values(
header_matches=header_matches))
op.drop_table('headermatch')
|