File .idea/workspace.xml added (mode: 100755) (index 0000000..e6feed4) |
|
1 |
|
<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
|
<project version="4"> |
|
3 |
|
<component name="ChangeListManager"> |
|
4 |
|
<list default="true" id="768bf4ae-35c8-4f55-b532-09088a37edd1" name="Default Changelist" comment="" /> |
|
5 |
|
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" /> |
|
6 |
|
<option name="SHOW_DIALOG" value="false" /> |
|
7 |
|
<option name="HIGHLIGHT_CONFLICTS" value="true" /> |
|
8 |
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> |
|
9 |
|
<option name="LAST_RESOLUTION" value="IGNORE" /> |
|
10 |
|
</component> |
|
11 |
|
<component name="FileTemplateManagerImpl"> |
|
12 |
|
<option name="RECENT_TEMPLATES"> |
|
13 |
|
<list> |
|
14 |
|
<option value="Python Script" /> |
|
15 |
|
<option value="HTML File" /> |
|
16 |
|
</list> |
|
17 |
|
</option> |
|
18 |
|
</component> |
|
19 |
|
<component name="ProjectId" id="1Sz8iGPOTTKy0jAH5Cm31rcCsJ8" /> |
|
20 |
|
<component name="PropertiesComponent"> |
|
21 |
|
<property name="DefaultHtmlFileTemplate" value="HTML File" /> |
|
22 |
|
<property name="last_opened_file_path" value="$PROJECT_DIR$" /> |
|
23 |
|
</component> |
|
24 |
|
<component name="RunDashboard"> |
|
25 |
|
<option name="ruleStates"> |
|
26 |
|
<list> |
|
27 |
|
<RuleState> |
|
28 |
|
<option name="name" value="ConfigurationTypeDashboardGroupingRule" /> |
|
29 |
|
</RuleState> |
|
30 |
|
<RuleState> |
|
31 |
|
<option name="name" value="StatusDashboardGroupingRule" /> |
|
32 |
|
</RuleState> |
|
33 |
|
</list> |
|
34 |
|
</option> |
|
35 |
|
</component> |
|
36 |
|
<component name="RunManager"> |
|
37 |
|
<configuration name="TodoList_flask" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true"> |
|
38 |
|
<module name="TodoList_flask" /> |
|
39 |
|
<option name="INTERPRETER_OPTIONS" value="" /> |
|
40 |
|
<option name="PARENT_ENVS" value="true" /> |
|
41 |
|
<envs> |
|
42 |
|
<env name="PYTHONUNBUFFERED" value="1" /> |
|
43 |
|
</envs> |
|
44 |
|
<option name="SDK_HOME" value="/usr/bin/python3.7" /> |
|
45 |
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/.." /> |
|
46 |
|
<option name="IS_MODULE_SDK" value="false" /> |
|
47 |
|
<option name="ADD_CONTENT_ROOTS" value="true" /> |
|
48 |
|
<option name="ADD_SOURCE_ROOTS" value="true" /> |
|
49 |
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$" /> |
|
50 |
|
<option name="PARAMETERS" value="" /> |
|
51 |
|
<option name="SHOW_COMMAND_LINE" value="false" /> |
|
52 |
|
<option name="EMULATE_TERMINAL" value="true" /> |
|
53 |
|
<option name="MODULE_MODE" value="false" /> |
|
54 |
|
<option name="REDIRECT_INPUT" value="false" /> |
|
55 |
|
<option name="INPUT_FILE" value="" /> |
|
56 |
|
<method v="2" /> |
|
57 |
|
</configuration> |
|
58 |
|
<configuration default="true" type="PythonConfigurationType" factoryName="Python"> |
|
59 |
|
<module name="TodoList_flask" /> |
|
60 |
|
<option name="INTERPRETER_OPTIONS" value="" /> |
|
61 |
|
<option name="PARENT_ENVS" value="true" /> |
|
62 |
|
<envs> |
|
63 |
|
<env name="PYTHONUNBUFFERED" value="1" /> |
|
64 |
|
</envs> |
|
65 |
|
<option name="SDK_HOME" value="/usr/bin/python3.7" /> |
|
66 |
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/.." /> |
|
67 |
|
<option name="IS_MODULE_SDK" value="false" /> |
|
68 |
|
<option name="ADD_CONTENT_ROOTS" value="true" /> |
|
69 |
|
<option name="ADD_SOURCE_ROOTS" value="true" /> |
|
70 |
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$" /> |
|
71 |
|
<option name="PARAMETERS" value="" /> |
|
72 |
|
<option name="SHOW_COMMAND_LINE" value="false" /> |
|
73 |
|
<option name="EMULATE_TERMINAL" value="true" /> |
|
74 |
|
<option name="MODULE_MODE" value="false" /> |
|
75 |
|
<option name="REDIRECT_INPUT" value="false" /> |
|
76 |
|
<option name="INPUT_FILE" value="" /> |
|
77 |
|
<method v="2" /> |
|
78 |
|
</configuration> |
|
79 |
|
</component> |
|
80 |
|
<component name="SvnConfiguration"> |
|
81 |
|
<configuration /> |
|
82 |
|
</component> |
|
83 |
|
<component name="TaskManager"> |
|
84 |
|
<task active="true" id="Default" summary="Default task"> |
|
85 |
|
<changelist id="768bf4ae-35c8-4f55-b532-09088a37edd1" name="Default Changelist" comment="" /> |
|
86 |
|
<created>1572555188390</created> |
|
87 |
|
<option name="number" value="Default" /> |
|
88 |
|
<option name="presentableId" value="Default" /> |
|
89 |
|
<updated>1572555188390</updated> |
|
90 |
|
</task> |
|
91 |
|
<servers /> |
|
92 |
|
</component> |
|
93 |
|
<component name="XDebuggerManager"> |
|
94 |
|
<breakpoint-manager> |
|
95 |
|
<breakpoints> |
|
96 |
|
<line-breakpoint enabled="true" suspend="THREAD" type="python-line"> |
|
97 |
|
<url>file://$PROJECT_DIR$/app/models.py</url> |
|
98 |
|
<option name="timeStamp" value="1" /> |
|
99 |
|
</line-breakpoint> |
|
100 |
|
</breakpoints> |
|
101 |
|
</breakpoint-manager> |
|
102 |
|
</component> |
|
103 |
|
</project> |
File migrations/env.py added (mode: 100644) (index 0000000..23663ff) |
|
1 |
|
from __future__ import with_statement |
|
2 |
|
from alembic import context |
|
3 |
|
from sqlalchemy import engine_from_config, pool |
|
4 |
|
from logging.config import fileConfig |
|
5 |
|
import logging |
|
6 |
|
|
|
7 |
|
# this is the Alembic Config object, which provides |
|
8 |
|
# access to the values within the .ini file in use. |
|
9 |
|
config = context.config |
|
10 |
|
|
|
11 |
|
# Interpret the config file for Python logging. |
|
12 |
|
# This line sets up loggers basically. |
|
13 |
|
fileConfig(config.config_file_name) |
|
14 |
|
logger = logging.getLogger('alembic.env') |
|
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 |
|
from flask import current_app |
|
21 |
|
config.set_main_option('sqlalchemy.url', |
|
22 |
|
current_app.config.get('SQLALCHEMY_DATABASE_URI')) |
|
23 |
|
target_metadata = current_app.extensions['migrate'].db.metadata |
|
24 |
|
|
|
25 |
|
# other values from the config, defined by the needs of env.py, |
|
26 |
|
# can be acquired: |
|
27 |
|
# my_important_option = config.get_main_option("my_important_option") |
|
28 |
|
# ... etc. |
|
29 |
|
|
|
30 |
|
|
|
31 |
|
def run_migrations_offline(): |
|
32 |
|
"""Run migrations in 'offline' mode. |
|
33 |
|
|
|
34 |
|
This configures the context with just a URL |
|
35 |
|
and not an Engine, though an Engine is acceptable |
|
36 |
|
here as well. By skipping the Engine creation |
|
37 |
|
we don't even need a DBAPI to be available. |
|
38 |
|
|
|
39 |
|
Calls to context.execute() here emit the given string to the |
|
40 |
|
script output. |
|
41 |
|
|
|
42 |
|
""" |
|
43 |
|
url = config.get_main_option("sqlalchemy.url") |
|
44 |
|
context.configure(url=url) |
|
45 |
|
|
|
46 |
|
with context.begin_transaction(): |
|
47 |
|
context.run_migrations() |
|
48 |
|
|
|
49 |
|
|
|
50 |
|
def run_migrations_online(): |
|
51 |
|
"""Run migrations in 'online' mode. |
|
52 |
|
|
|
53 |
|
In this scenario we need to create an Engine |
|
54 |
|
and associate a connection with the context. |
|
55 |
|
|
|
56 |
|
""" |
|
57 |
|
|
|
58 |
|
# this callback is used to prevent an auto-migration from being generated |
|
59 |
|
# when there are no changes to the schema |
|
60 |
|
# reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html |
|
61 |
|
def process_revision_directives(context, revision, directives): |
|
62 |
|
if getattr(config.cmd_opts, 'autogenerate', False): |
|
63 |
|
script = directives[0] |
|
64 |
|
if script.upgrade_ops.is_empty(): |
|
65 |
|
directives[:] = [] |
|
66 |
|
logger.info('No changes in schema detected.') |
|
67 |
|
|
|
68 |
|
engine = engine_from_config(config.get_section(config.config_ini_section), |
|
69 |
|
prefix='sqlalchemy.', |
|
70 |
|
poolclass=pool.NullPool) |
|
71 |
|
|
|
72 |
|
connection = engine.connect() |
|
73 |
|
context.configure(connection=connection, |
|
74 |
|
target_metadata=target_metadata, |
|
75 |
|
process_revision_directives=process_revision_directives, |
|
76 |
|
**current_app.extensions['migrate'].configure_args) |
|
77 |
|
|
|
78 |
|
try: |
|
79 |
|
with context.begin_transaction(): |
|
80 |
|
context.run_migrations() |
|
81 |
|
finally: |
|
82 |
|
connection.close() |
|
83 |
|
|
|
84 |
|
if context.is_offline_mode(): |
|
85 |
|
run_migrations_offline() |
|
86 |
|
else: |
|
87 |
|
run_migrations_online() |
File migrations/versions/00b0da5d3ec9_.py added (mode: 100644) (index 0000000..6f920da) |
|
1 |
|
"""empty message |
|
2 |
|
|
|
3 |
|
Revision ID: 00b0da5d3ec9 |
|
4 |
|
Revises: |
|
5 |
|
Create Date: 2019-11-03 10:53:30.104425 |
|
6 |
|
|
|
7 |
|
""" |
|
8 |
|
from alembic import op |
|
9 |
|
import sqlalchemy as sa |
|
10 |
|
|
|
11 |
|
|
|
12 |
|
# revision identifiers, used by Alembic. |
|
13 |
|
revision = '00b0da5d3ec9' |
|
14 |
|
down_revision = None |
|
15 |
|
branch_labels = None |
|
16 |
|
depends_on = None |
|
17 |
|
|
|
18 |
|
|
|
19 |
|
def upgrade(): |
|
20 |
|
# ### commands auto generated by Alembic - please adjust! ### |
|
21 |
|
op.create_table('user', |
|
22 |
|
sa.Column('id', sa.Integer(), nullable=False), |
|
23 |
|
sa.Column('username', sa.String(length=64), nullable=True), |
|
24 |
|
sa.Column('email', sa.String(length=120), nullable=True), |
|
25 |
|
sa.Column('password_hash', sa.String(length=128), nullable=True), |
|
26 |
|
sa.PrimaryKeyConstraint('id') |
|
27 |
|
) |
|
28 |
|
op.create_index(op.f('ix_user_email'), 'user', ['email'], unique=True) |
|
29 |
|
op.create_index(op.f('ix_user_username'), 'user', ['username'], unique=True) |
|
30 |
|
op.create_table('todo', |
|
31 |
|
sa.Column('id', sa.Integer(), nullable=False), |
|
32 |
|
sa.Column('title', sa.String(length=1400), nullable=True), |
|
33 |
|
sa.Column('body', sa.String(length=1400), nullable=True), |
|
34 |
|
sa.Column('timestamp', sa.DateTime(), nullable=True), |
|
35 |
|
sa.Column('user_id', sa.Integer(), nullable=True), |
|
36 |
|
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), |
|
37 |
|
sa.PrimaryKeyConstraint('id') |
|
38 |
|
) |
|
39 |
|
op.create_index(op.f('ix_todo_timestamp'), 'todo', ['timestamp'], unique=False) |
|
40 |
|
# ### end Alembic commands ### |
|
41 |
|
|
|
42 |
|
|
|
43 |
|
def downgrade(): |
|
44 |
|
# ### commands auto generated by Alembic - please adjust! ### |
|
45 |
|
op.drop_index(op.f('ix_todo_timestamp'), table_name='todo') |
|
46 |
|
op.drop_table('todo') |
|
47 |
|
op.drop_index(op.f('ix_user_username'), table_name='user') |
|
48 |
|
op.drop_index(op.f('ix_user_email'), table_name='user') |
|
49 |
|
op.drop_table('user') |
|
50 |
|
# ### end Alembic commands ### |
File migrations/versions/1987486c0538_.py added (mode: 100644) (index 0000000..cc8da23) |
|
1 |
|
"""empty message |
|
2 |
|
|
|
3 |
|
Revision ID: 1987486c0538 |
|
4 |
|
Revises: 00b0da5d3ec9 |
|
5 |
|
Create Date: 2019-11-03 11:36:21.733205 |
|
6 |
|
|
|
7 |
|
""" |
|
8 |
|
from alembic import op |
|
9 |
|
import sqlalchemy as sa |
|
10 |
|
|
|
11 |
|
|
|
12 |
|
# revision identifiers, used by Alembic. |
|
13 |
|
revision = '1987486c0538' |
|
14 |
|
down_revision = '00b0da5d3ec9' |
|
15 |
|
branch_labels = None |
|
16 |
|
depends_on = None |
|
17 |
|
|
|
18 |
|
|
|
19 |
|
def upgrade(): |
|
20 |
|
# ### commands auto generated by Alembic - please adjust! ### |
|
21 |
|
op.add_column('user', sa.Column('name', sa.String(length=64), nullable=True)) |
|
22 |
|
op.add_column('user', sa.Column('password', sa.String(length=128), nullable=True)) |
|
23 |
|
op.create_index(op.f('ix_user_name'), 'user', ['name'], unique=True) |
|
24 |
|
op.drop_column('user', 'password_hash') |
|
25 |
|
# ### end Alembic commands ### |
|
26 |
|
|
|
27 |
|
|
|
28 |
|
def downgrade(): |
|
29 |
|
# ### commands auto generated by Alembic - please adjust! ### |
|
30 |
|
op.add_column('user', sa.Column('password_hash', sa.VARCHAR(length=128), autoincrement=False, nullable=True)) |
|
31 |
|
op.drop_index(op.f('ix_user_name'), table_name='user') |
|
32 |
|
op.drop_column('user', 'password') |
|
33 |
|
op.drop_column('user', 'name') |
|
34 |
|
# ### end Alembic commands ### |
File migrations/versions/d58397d23b87_.py added (mode: 100644) (index 0000000..f14bb88) |
|
1 |
|
"""empty message |
|
2 |
|
|
|
3 |
|
Revision ID: d58397d23b87 |
|
4 |
|
Revises: 1987486c0538 |
|
5 |
|
Create Date: 2019-11-04 00:47:42.064999 |
|
6 |
|
|
|
7 |
|
""" |
|
8 |
|
from alembic import op |
|
9 |
|
import sqlalchemy as sa |
|
10 |
|
from sqlalchemy.dialects import postgresql |
|
11 |
|
|
|
12 |
|
# revision identifiers, used by Alembic. |
|
13 |
|
revision = 'd58397d23b87' |
|
14 |
|
down_revision = '1987486c0538' |
|
15 |
|
branch_labels = None |
|
16 |
|
depends_on = None |
|
17 |
|
|
|
18 |
|
|
|
19 |
|
def upgrade(): |
|
20 |
|
# ### commands auto generated by Alembic - please adjust! ### |
|
21 |
|
op.add_column('todo', sa.Column('completed_date', sa.DateTime(), nullable=True)) |
|
22 |
|
op.add_column('todo', sa.Column('created_date', sa.DateTime(), nullable=True)) |
|
23 |
|
op.add_column('todo', sa.Column('modified_date', sa.DateTime(), nullable=True)) |
|
24 |
|
op.add_column('todo', sa.Column('recurring', sa.Boolean(), nullable=True)) |
|
25 |
|
op.add_column('todo', sa.Column('scheduled_date', sa.DateTime(), nullable=True)) |
|
26 |
|
op.add_column('todo', sa.Column('status', sa.String(length=1400), nullable=True)) |
|
27 |
|
op.create_index(op.f('ix_todo_completed_date'), 'todo', ['completed_date'], unique=False) |
|
28 |
|
op.create_index(op.f('ix_todo_created_date'), 'todo', ['created_date'], unique=False) |
|
29 |
|
op.create_index(op.f('ix_todo_modified_date'), 'todo', ['modified_date'], unique=False) |
|
30 |
|
op.create_index(op.f('ix_todo_scheduled_date'), 'todo', ['scheduled_date'], unique=False) |
|
31 |
|
op.drop_index('ix_todo_timestamp', table_name='todo') |
|
32 |
|
op.drop_column('todo', 'timestamp') |
|
33 |
|
# ### end Alembic commands ### |
|
34 |
|
|
|
35 |
|
|
|
36 |
|
def downgrade(): |
|
37 |
|
# ### commands auto generated by Alembic - please adjust! ### |
|
38 |
|
op.add_column('todo', sa.Column('timestamp', postgresql.TIMESTAMP(), autoincrement=False, nullable=True)) |
|
39 |
|
op.create_index('ix_todo_timestamp', 'todo', ['timestamp'], unique=False) |
|
40 |
|
op.drop_index(op.f('ix_todo_scheduled_date'), table_name='todo') |
|
41 |
|
op.drop_index(op.f('ix_todo_modified_date'), table_name='todo') |
|
42 |
|
op.drop_index(op.f('ix_todo_created_date'), table_name='todo') |
|
43 |
|
op.drop_index(op.f('ix_todo_completed_date'), table_name='todo') |
|
44 |
|
op.drop_column('todo', 'status') |
|
45 |
|
op.drop_column('todo', 'scheduled_date') |
|
46 |
|
op.drop_column('todo', 'recurring') |
|
47 |
|
op.drop_column('todo', 'modified_date') |
|
48 |
|
op.drop_column('todo', 'created_date') |
|
49 |
|
op.drop_column('todo', 'completed_date') |
|
50 |
|
# ### end Alembic commands ### |