Skip to content

Commit c2e4ffd

Browse files
author
施華桐
committed
start to use database migration
1 parent d007bc0 commit c2e4ffd

6 files changed

Lines changed: 292 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# ChangeLog
22

33
## [Unreleased]
4+
### Add
5+
- start to use database migration
46

57
## [1.0.1] 2018-12-24
68
### Chanage

db_migration/README

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Generic single-database configuration.

db_migration/env.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
from __future__ import with_statement
2+
import os
3+
import sys
4+
from alembic import context
5+
from sqlalchemy import engine_from_config, pool
6+
from logging.config import fileConfig
7+
8+
# this is the Alembic Config object, which provides
9+
# access to the values within the .ini file in use.
10+
config = context.config
11+
12+
# Interpret the config file for Python logging.
13+
# This line sets up loggers basically.
14+
fileConfig(config.config_file_name)
15+
16+
# add your model's MetaData object here
17+
# for 'autogenerate' support
18+
# from myapp import mymodel
19+
# target_metadata = mymodel.Base.metadata
20+
target_metadata = None
21+
22+
# other values from the config, defined by the needs of env.py,
23+
# can be acquired:
24+
# my_important_option = config.get_main_option("my_important_option")
25+
# ... etc.
26+
27+
28+
def run_migrations_offline():
29+
"""Run migrations in 'offline' mode.
30+
31+
This configures the context with just a URL
32+
and not an Engine, though an Engine is acceptable
33+
here as well. By skipping the Engine creation
34+
we don't even need a DBAPI to be available.
35+
36+
Calls to context.execute() here emit the given string to the
37+
script output.
38+
39+
"""
40+
url = config.get_main_option("sqlalchemy.url")
41+
context.configure(
42+
url=url, target_metadata=target_metadata,
43+
literal_binds=True)
44+
45+
with context.begin_transaction():
46+
context.run_migrations()
47+
48+
49+
def run_migrations_online():
50+
"""Run migrations in 'online' mode.
51+
52+
In this scenario we need to create an Engine
53+
and associate a connection with the context.
54+
55+
"""
56+
sys.path.append(os.getcwd())
57+
58+
from models.base import Base
59+
target_metadata = Base.metadata
60+
61+
connectable = engine_from_config(
62+
config.get_section(config.config_ini_section),
63+
prefix='sqlalchemy.',
64+
poolclass=pool.NullPool)
65+
66+
with connectable.connect() as connection:
67+
context.configure(
68+
connection=connection,
69+
target_metadata=target_metadata,
70+
compare_type=True,
71+
render_as_batch=True)
72+
73+
with context.begin_transaction():
74+
context.run_migrations()
75+
76+
77+
if context.is_offline_mode():
78+
run_migrations_offline()
79+
else:
80+
run_migrations_online()

db_migration/script.py.mako

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
"""${message}
2+
3+
Revision ID: ${up_revision}
4+
Revises: ${down_revision | comma,n}
5+
Create Date: ${create_date}
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
${imports if imports else ""}
11+
12+
# revision identifiers, used by Alembic.
13+
revision = ${repr(up_revision)}
14+
down_revision = ${repr(down_revision)}
15+
branch_labels = ${repr(branch_labels)}
16+
depends_on = ${repr(depends_on)}
17+
18+
19+
def upgrade():
20+
${upgrades if upgrades else "pass"}
21+
22+
23+
def downgrade():
24+
${downgrades if downgrades else "pass"}
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
"""create initial table
2+
3+
Revision ID: 77eaebfa8062
4+
Revises:
5+
Create Date: 2018-12-24 15:29:31.660830
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
11+
12+
# revision identifiers, used by Alembic.
13+
revision = '77eaebfa8062'
14+
down_revision = None
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
op.create_table('board',
21+
sa.Column('id',
22+
sa.Integer(),
23+
nullable=False),
24+
sa.Column('name',
25+
sa.String(length=64),
26+
nullable=False),
27+
sa.PrimaryKeyConstraint('id')
28+
)
29+
op.create_table('ip_asn',
30+
sa.Column('ip',
31+
sa.String(length=40),
32+
nullable=False),
33+
sa.Column('asn',
34+
sa.String(length=256),
35+
nullable=True),
36+
sa.Column('asn_date',
37+
sa.DateTime(),
38+
nullable=True),
39+
sa.Column('asn_registry',
40+
sa.String(length=256),
41+
nullable=True),
42+
sa.Column('asn_cidr',
43+
sa.String(length=256),
44+
nullable=True),
45+
sa.Column('asn_country_code',
46+
sa.String(length=4),
47+
nullable=True),
48+
sa.Column('asn_description',
49+
sa.String(length=256),
50+
nullable=True),
51+
sa.Column('asn_raw', sa.String(),
52+
nullable=True),
53+
sa.PrimaryKeyConstraint('ip')
54+
)
55+
op.create_table('user',
56+
sa.Column('id',
57+
sa.Integer(),
58+
nullable=False),
59+
sa.Column('username',
60+
sa.String(length=32),
61+
nullable=False),
62+
sa.Column('login_times',
63+
sa.Integer(),
64+
nullable=True),
65+
sa.Column('valid_article_count',
66+
sa.Integer(),
67+
nullable=True),
68+
sa.PrimaryKeyConstraint('id'),
69+
sa.UniqueConstraint('username')
70+
)
71+
op.create_table('article',
72+
sa.Column('id',
73+
sa.Integer(),
74+
nullable=False),
75+
sa.Column('web_id',
76+
sa.String(length=20),
77+
nullable=False),
78+
sa.Column('user_id',
79+
sa.Integer(),
80+
nullable=False),
81+
sa.Column('board_id',
82+
sa.Integer(),
83+
nullable=False),
84+
sa.Column('post_datetime',
85+
sa.DateTime(),
86+
nullable=False),
87+
sa.Column('post_ip',
88+
sa.String(length=20),
89+
nullable=False),
90+
sa.ForeignKeyConstraint(['board_id'],
91+
['board.id'], ),
92+
sa.ForeignKeyConstraint(['user_id'],
93+
['user.id'], ),
94+
sa.PrimaryKeyConstraint('id')
95+
)
96+
op.create_table('user_last_record',
97+
sa.Column('id',
98+
sa.Integer(),
99+
nullable=False),
100+
sa.Column('user_id',
101+
sa.Integer(),
102+
nullable=False),
103+
sa.Column('last_login_datetime',
104+
sa.DateTime(),
105+
nullable=False),
106+
sa.Column('last_login_ip',
107+
sa.String(length=40),
108+
nullable=False),
109+
sa.Column('created_at',
110+
sa.DateTime(),
111+
nullable=False),
112+
sa.ForeignKeyConstraint(['user_id'],
113+
['user.id'], ),
114+
sa.PrimaryKeyConstraint('id')
115+
)
116+
op.create_table('article_history',
117+
sa.Column('id',
118+
sa.Integer(),
119+
nullable=False),
120+
sa.Column('article_id',
121+
sa.Integer(),
122+
nullable=False),
123+
sa.Column('title',
124+
sa.String(length=64),
125+
nullable=False),
126+
sa.Column('content',
127+
sa.String(),
128+
nullable=False),
129+
sa.Column('start_at',
130+
sa.DateTime(),
131+
nullable=False),
132+
sa.Column('end_at',
133+
sa.DateTime(),
134+
nullable=False),
135+
sa.ForeignKeyConstraint(['article_id'],
136+
['article.id'], ),
137+
sa.PrimaryKeyConstraint('id')
138+
)
139+
op.create_table('push',
140+
sa.Column('id',
141+
sa.Integer(),
142+
nullable=False),
143+
sa.Column('article_history_id',
144+
sa.Integer(),
145+
nullable=False),
146+
sa.Column('floor',
147+
sa.Integer(),
148+
nullable=False),
149+
sa.Column('push_tag',
150+
sa.String(length=2),
151+
nullable=False),
152+
sa.Column('push_user_id',
153+
sa.Integer(),
154+
nullable=False),
155+
sa.Column('push_content',
156+
sa.String(
157+
length=128),
158+
nullable=False),
159+
sa.Column('push_ip',
160+
sa.String(length=40),
161+
nullable=True),
162+
sa.Column('push_datetime',
163+
sa.DateTime(),
164+
nullable=False),
165+
sa.ForeignKeyConstraint(['article_history_id'],
166+
['article_history.id'], ),
167+
sa.ForeignKeyConstraint(['push_user_id'],
168+
['user.id'], ),
169+
sa.PrimaryKeyConstraint('id')
170+
)
171+
172+
173+
def downgrade():
174+
op.drop_table('push')
175+
op.drop_table('article_history')
176+
op.drop_table('user_last_record')
177+
op.drop_table('article')
178+
op.drop_table('user')
179+
op.drop_table('ip_asn')
180+
op.drop_table('board')

models/base.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ def __init__(self, dbtype, username='', password='', dbname=''):
1919

2020
if dbtype in self.DB_ENGINE.keys():
2121

22-
folder = os.path.dirname(dbname)
23-
if folder != '':
24-
if not os.path.exists(folder):
25-
os.makedirs(folder)
22+
# folder = os.path.dirname(dbname)
23+
# if folder != '':
24+
# if not os.path.exists(folder):
25+
# os.makedirs(folder)
2626

2727
engine_url = self.DB_ENGINE[dbtype].format(DB=dbname)
2828
self.engine = create_engine(engine_url)
29-
Base.metadata.create_all(self.engine, checkfirst=True)
29+
# Base.metadata.create_all(self.engine, checkfirst=True)
3030
else:
3131
raise ValueError("DBType is not found in DB_ENGINE")
3232

0 commit comments

Comments
 (0)