push
This commit is contained in:
1
migrations/README.txt
Normal file
1
migrations/README.txt
Normal file
@@ -0,0 +1 @@
|
||||
Initial project migration placeholder. Use `flask --app run.py db init`, `flask --app run.py db migrate`, `flask --app run.py db upgrade` to regenerate against the current models.
|
||||
35
migrations/alembic.ini
Normal file
35
migrations/alembic.ini
Normal file
@@ -0,0 +1,35 @@
|
||||
[alembic]
|
||||
script_location = migrations
|
||||
|
||||
[loggers]
|
||||
keys = root,sqlalchemy,alembic
|
||||
|
||||
[handlers]
|
||||
keys = console
|
||||
|
||||
[formatters]
|
||||
keys = generic
|
||||
|
||||
[logger_root]
|
||||
level = WARN
|
||||
handlers = console
|
||||
|
||||
[logger_sqlalchemy]
|
||||
level = WARN
|
||||
handlers =
|
||||
qualname = sqlalchemy.engine
|
||||
|
||||
[logger_alembic]
|
||||
level = INFO
|
||||
handlers =
|
||||
qualname = alembic
|
||||
|
||||
[handler_console]
|
||||
class = StreamHandler
|
||||
args = (sys.stderr,)
|
||||
level = NOTSET
|
||||
formatter = generic
|
||||
|
||||
[formatter_generic]
|
||||
format = %(levelname)-5.5s [%(name)s] %(message)s
|
||||
datefmt = %H:%M:%S
|
||||
86
migrations/env.py
Normal file
86
migrations/env.py
Normal file
@@ -0,0 +1,86 @@
|
||||
from __future__ import with_statement
|
||||
|
||||
from logging.config import fileConfig
|
||||
|
||||
from flask import current_app
|
||||
|
||||
from alembic import context
|
||||
|
||||
config = context.config
|
||||
|
||||
fileConfig(config.config_file_name)
|
||||
logger = fileConfig
|
||||
|
||||
|
||||
def get_engine():
|
||||
try:
|
||||
return current_app.extensions['migrate'].db.get_engine()
|
||||
except (TypeError, AttributeError):
|
||||
return current_app.extensions['migrate'].db.engine
|
||||
|
||||
|
||||
def get_engine_url():
|
||||
try:
|
||||
return get_engine().url.render_as_string(hide_password=False).replace('%', '%%')
|
||||
except AttributeError:
|
||||
return str(get_engine().url).replace('%', '%%')
|
||||
|
||||
|
||||
config.set_main_option('sqlalchemy.url', get_engine_url())
|
||||
target_db = current_app.extensions['migrate'].db
|
||||
|
||||
|
||||
def get_metadata():
|
||||
if hasattr(target_db, 'metadatas'):
|
||||
return target_db.metadatas[None]
|
||||
return target_db.metadata
|
||||
|
||||
|
||||
def run_migrations_offline():
|
||||
url = config.get_main_option('sqlalchemy.url')
|
||||
conf_args = dict(current_app.extensions['migrate'].configure_args)
|
||||
conf_args.setdefault('compare_type', True)
|
||||
conf_args.setdefault('render_as_batch', True)
|
||||
|
||||
context.configure(
|
||||
url=url,
|
||||
target_metadata=get_metadata(),
|
||||
literal_binds=True,
|
||||
**conf_args,
|
||||
)
|
||||
|
||||
with context.begin_transaction():
|
||||
context.run_migrations()
|
||||
|
||||
|
||||
def run_migrations_online():
|
||||
conf_args = dict(current_app.extensions['migrate'].configure_args)
|
||||
if conf_args.get('process_revision_directives') is None:
|
||||
def process_revision_directives(context_, revision, directives):
|
||||
if getattr(config.cmd_opts, 'autogenerate', False):
|
||||
script = directives[0]
|
||||
if script.upgrade_ops.is_empty():
|
||||
directives[:] = []
|
||||
print('No changes in schema detected.')
|
||||
conf_args['process_revision_directives'] = process_revision_directives
|
||||
|
||||
connectable = get_engine()
|
||||
|
||||
with connectable.connect() as connection:
|
||||
conf_args.setdefault('compare_type', True)
|
||||
conf_args.setdefault('render_as_batch', True)
|
||||
|
||||
context.configure(
|
||||
connection=connection,
|
||||
target_metadata=get_metadata(),
|
||||
**conf_args,
|
||||
)
|
||||
|
||||
with context.begin_transaction():
|
||||
context.run_migrations()
|
||||
|
||||
|
||||
if context.is_offline_mode():
|
||||
run_migrations_offline()
|
||||
else:
|
||||
run_migrations_online()
|
||||
24
migrations/script.py.mako
Normal file
24
migrations/script.py.mako
Normal file
@@ -0,0 +1,24 @@
|
||||
"""${message}
|
||||
|
||||
Revision ID: ${up_revision}
|
||||
Revises: ${down_revision | comma,n}
|
||||
Create Date: ${create_date}
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
${imports if imports else ""}
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = ${repr(up_revision)}
|
||||
down_revision = ${repr(down_revision)}
|
||||
branch_labels = ${repr(branch_labels)}
|
||||
depends_on = ${repr(depends_on)}
|
||||
|
||||
|
||||
def upgrade():
|
||||
${upgrades if upgrades else "pass"}
|
||||
|
||||
|
||||
def downgrade():
|
||||
${downgrades if downgrades else "pass"}
|
||||
@@ -0,0 +1,9 @@
|
||||
-- SQLite migration for split payment support
|
||||
-- Run once on an existing database.
|
||||
|
||||
ALTER TABLE product ADD COLUMN split_payment_default INTEGER NOT NULL DEFAULT 0;
|
||||
ALTER TABLE invoice ADD COLUMN split_payment INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
-- Optional backfill examples:
|
||||
-- UPDATE product SET split_payment_default = 1 WHERE name IN ('Usługa A', 'Usługa B');
|
||||
-- UPDATE invoice SET split_payment = 1 WHERE gross_amount >= 15000;
|
||||
@@ -0,0 +1,9 @@
|
||||
ALTER TABLE company ADD COLUMN bank_account VARCHAR(64) DEFAULT '';
|
||||
ALTER TABLE invoice ADD COLUMN seller_bank_account VARCHAR(64) DEFAULT '';
|
||||
|
||||
-- Optional backfill from current company data for already issued invoices:
|
||||
-- UPDATE invoice
|
||||
-- SET seller_bank_account = (
|
||||
-- SELECT company.bank_account FROM company WHERE company.id = invoice.company_id
|
||||
-- )
|
||||
-- WHERE COALESCE(seller_bank_account, '') = '';
|
||||
@@ -0,0 +1,50 @@
|
||||
"""add contractor regon and address to invoice
|
||||
|
||||
Revision ID: add_invoice_contractor_fields
|
||||
Revises:
|
||||
Create Date: 2026-03-10 12:00:00.000000
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import inspect
|
||||
|
||||
|
||||
revision = "add_invoice_contractor_fields"
|
||||
down_revision = None
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def _has_column(table_name: str, column_name: str) -> bool:
|
||||
bind = op.get_bind()
|
||||
inspector = inspect(bind)
|
||||
return column_name in {col["name"] for col in inspector.get_columns(table_name)}
|
||||
|
||||
|
||||
def _has_index(table_name: str, index_name: str) -> bool:
|
||||
bind = op.get_bind()
|
||||
inspector = inspect(bind)
|
||||
return index_name in {idx["name"] for idx in inspector.get_indexes(table_name)}
|
||||
|
||||
|
||||
def upgrade():
|
||||
with op.batch_alter_table("invoice", schema=None) as batch_op:
|
||||
if not _has_column("invoice", "contractor_regon"):
|
||||
batch_op.add_column(sa.Column("contractor_regon", sa.String(length=32), nullable=True))
|
||||
if not _has_column("invoice", "contractor_address"):
|
||||
batch_op.add_column(sa.Column("contractor_address", sa.String(length=512), nullable=True))
|
||||
index_name = batch_op.f("ix_invoice_contractor_regon")
|
||||
if _has_column("invoice", "contractor_regon") and not _has_index("invoice", index_name):
|
||||
batch_op.create_index(index_name, ["contractor_regon"], unique=False)
|
||||
|
||||
|
||||
def downgrade():
|
||||
with op.batch_alter_table("invoice", schema=None) as batch_op:
|
||||
index_name = batch_op.f("ix_invoice_contractor_regon")
|
||||
if _has_index("invoice", index_name):
|
||||
batch_op.drop_index(index_name)
|
||||
if _has_column("invoice", "contractor_address"):
|
||||
batch_op.drop_column("contractor_address")
|
||||
if _has_column("invoice", "contractor_regon"):
|
||||
batch_op.drop_column("contractor_regon")
|
||||
@@ -0,0 +1,42 @@
|
||||
"""add split payment and mail security
|
||||
|
||||
Revision ID: 002_add_split_payment_and_mail_security
|
||||
Revises: add_invoice_contractor_fields
|
||||
Create Date: 2026-03-12
|
||||
"""
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import inspect
|
||||
|
||||
|
||||
revision = '002_add_split_payment_and_mail_security'
|
||||
down_revision = 'add_invoice_contractor_fields'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def _has_column(table_name: str, column_name: str) -> bool:
|
||||
bind = op.get_bind()
|
||||
inspector = inspect(bind)
|
||||
return column_name in {col["name"] for col in inspector.get_columns(table_name)}
|
||||
|
||||
|
||||
def upgrade():
|
||||
with op.batch_alter_table('product') as batch_op:
|
||||
if not _has_column('product', 'split_payment_default'):
|
||||
batch_op.add_column(sa.Column('split_payment_default', sa.Boolean(), nullable=False, server_default=sa.false()))
|
||||
|
||||
with op.batch_alter_table('invoice') as batch_op:
|
||||
if not _has_column('invoice', 'split_payment'):
|
||||
batch_op.add_column(sa.Column('split_payment', sa.Boolean(), nullable=False, server_default=sa.false()))
|
||||
|
||||
|
||||
def downgrade():
|
||||
with op.batch_alter_table('invoice') as batch_op:
|
||||
if _has_column('invoice', 'split_payment'):
|
||||
batch_op.drop_column('split_payment')
|
||||
|
||||
with op.batch_alter_table('product') as batch_op:
|
||||
if _has_column('product', 'split_payment_default'):
|
||||
batch_op.drop_column('split_payment_default')
|
||||
@@ -0,0 +1,44 @@
|
||||
"""add bank account to company and invoice
|
||||
|
||||
Revision ID: 003_add_bank_account_to_company_and_invoice
|
||||
Revises: 002_add_split_payment_and_mail_security
|
||||
Create Date: 2026-03-12
|
||||
"""
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import inspect
|
||||
|
||||
revision = '003_add_bank_account_to_company_and_invoice'
|
||||
down_revision = '002_add_split_payment_and_mail_security'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def _has_column(table_name: str, column_name: str) -> bool:
|
||||
bind = op.get_bind()
|
||||
inspector = inspect(bind)
|
||||
return column_name in {col['name'] for col in inspector.get_columns(table_name)}
|
||||
|
||||
|
||||
def upgrade():
|
||||
with op.batch_alter_table('company') as batch_op:
|
||||
if not _has_column('company', 'bank_account'):
|
||||
batch_op.add_column(sa.Column('bank_account', sa.String(length=64), nullable=True, server_default=''))
|
||||
|
||||
with op.batch_alter_table('invoice') as batch_op:
|
||||
if not _has_column('invoice', 'seller_bank_account'):
|
||||
batch_op.add_column(sa.Column('seller_bank_account', sa.String(length=64), nullable=True, server_default=''))
|
||||
|
||||
op.execute("UPDATE invoice SET seller_bank_account = COALESCE(seller_bank_account, '')")
|
||||
op.execute("UPDATE company SET bank_account = COALESCE(bank_account, '')")
|
||||
|
||||
|
||||
def downgrade():
|
||||
with op.batch_alter_table('invoice') as batch_op:
|
||||
if _has_column('invoice', 'seller_bank_account'):
|
||||
batch_op.drop_column('seller_bank_account')
|
||||
|
||||
with op.batch_alter_table('company') as batch_op:
|
||||
if _has_column('company', 'bank_account'):
|
||||
batch_op.drop_column('bank_account')
|
||||
Reference in New Issue
Block a user