refactor(extend db upgrade): 重新整合二开新增表的hash历史,以及新增迁移命令

This commit is contained in:
FamousMai
2025-04-11 11:38:42 +08:00
parent 906f5a0da5
commit b361b83368
16 changed files with 642 additions and 243 deletions
+66
View File
@@ -814,3 +814,69 @@ def clear_free_plan_tenant_expired_logs(days: int, batch: int, tenant_ids: list[
ClearFreePlanTenantExpiredLogs.process(days, batch, tenant_ids)
click.echo(click.style("Clear free plan tenant expired logs completed.", fg="green"))
@click.group("extend_db", help="管理二开扩展表的数据库迁移")
def extend_db():
"""管理二开扩展表的数据库迁移"""
pass
@extend_db.command("upgrade", help="将数据库升级到最新版本")
@click.option("--revision", default="head", help="目标版本,默认为最新版本(head)")
def extend_db_upgrade(revision):
"""将数据库升级到指定版本(默认为最新版本)"""
_run_alembic_command_extend("upgrade", revision)
@extend_db.command("downgrade", help="回滚数据库到指定版本")
@click.option("--revision", required=True, help="目标版本")
def extend_db_downgrade(revision):
"""回滚数据库到指定版本"""
_run_alembic_command_extend("downgrade", revision)
@extend_db.command("current", help="显示当前数据库版本")
def extend_db_current():
"""显示当前数据库版本"""
_run_alembic_command_extend("current")
@extend_db.command("history", help="显示迁移历史")
def extend_db_history():
"""显示迁移历史"""
_run_alembic_command_extend("history")
@extend_db.command("heads", help="显示最新的迁移版本")
def extend_db_heads():
"""显示最新的迁移版本"""
_run_alembic_command_extend("heads")
def _run_alembic_command_extend(command, *args):
"""运行 alembic 命令"""
import os
import sys
from flask import current_app
from alembic.config import Config
from alembic import command as alembic_command
# 获取 api 目录的绝对路径
api_dir = os.path.abspath(os.path.dirname(__file__))
migrations_extend_dir = os.path.join(api_dir, 'migrations_extend')
# 创建alembic配置
alembic_cfg = Config(os.path.join(migrations_extend_dir, 'alembic.ini'))
alembic_cfg.set_main_option('script_location', migrations_extend_dir)
# 获取相应的alembic命令函数
cmd_func = getattr(alembic_command, command)
# 在Flask应用上下文中执行alembic命令
with current_app.app_context():
# 执行命令
if args:
cmd_func(alembic_cfg, *args)
else:
cmd_func(alembic_cfg)
+2
View File
@@ -7,6 +7,7 @@ def init_app(app: DifyApp):
clear_free_plan_tenant_expired_logs,
convert_to_agent_apps,
create_tenant,
extend_db,
extract_plugins,
extract_unique_plugins,
fix_app_site_missing,
@@ -36,6 +37,7 @@ def init_app(app: DifyApp):
install_plugins,
old_metadata_migration,
clear_free_plan_tenant_expired_logs,
extend_db,
]
for cmd in cmds_to_register:
app.cli.add_command(cmd)
+54
View File
@@ -0,0 +1,54 @@
# 二开扩展表迁移说明
这个目录包含了二开扩展的数据库迁移文件,用于管理二开项目中添加的新表。
## 如何使用
### 使用 Flask 命令(推荐)
我们提供了与原始项目类似的 Flask 命令来管理二开扩展表的迁移:
```bash
# 升级数据库到最新版本
flask extend_db upgrade
# 回滚数据库到指定版本
flask extend_db downgrade --revision 版本号
# 查看当前数据库版本
flask extend_db current
# 查看迁移历史
flask extend_db history
# 查看最新的迁移版本
flask extend_db heads
```
### 检查当前数据库版本
要查看当前数据库的版本,请运行:
```bash
flask extend_db current
```
### 降级数据库
如果需要回滚迁移,可以使用:
```bash
flask extend_db downgrade --revision 版本号
```
例如,回滚到 `001_recommended_list_sorted`
```bash
flask extend_db downgrade --revision 001_recommended_list_sorted
```
## 注意事项
1. 这些迁移文件仅适用于二开扩展的表,不会影响原有系统表。
2. 所有迁移文件都已添加表存在性检查,可以多次运行而不会出错。
3. 如果需要添加新的迁移文件,请确保正确设置前置版本(Revises)值。
4. 使用 Flask 命令时确保在项目 `api` 下运行,而不是根目录下。
+84
View File
@@ -0,0 +1,84 @@
# A generic, single database configuration.
[alembic]
# path to migration scripts
script_location = .
# template used to generate migration files
# file_template = %%(rev)s_%%(slug)s
# timezone to use when rendering the date
# within the migration file as well as the filename.
# string value is passed to dateutil.tz.gettz()
# leave blank for localtime
# timezone =
# max length of characters to apply to the
# "slug" field
# truncate_slug_length = 40
# set to 'true' to run the environment during
# the 'revision' command, regardless of autogenerate
# revision_environment = false
# set to 'true' to allow .pyc and .pyo files without
# a source .py file to be detected as revisions in the
# versions/ directory
# sourceless = false
# version location specification; this defaults
# to migrations/versions. When using multiple version
# directories, initial revisions must be specified with --version-path
# version_locations = %(here)s/bar %(here)s/bat migrations/versions
# the output encoding used when revision files
# are written from script.py.mako
# output_encoding = utf-8
sqlalchemy.url = postgresql+psycopg2://postgres:difyai123456@localhost:5432/dify_develop_test
[post_write_hooks]
# post_write_hooks defines scripts or Python functions that are run
# on newly generated revision scripts. See the documentation for further
# detail and examples
# format using "black" - use the console_scripts runner, against the "black" entrypoint
# hooks=black
# black.type=console_scripts
# black.entrypoint=black
# black.options=-l 79
# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = WARN
handlers = console
qualname =
[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
+100
View File
@@ -0,0 +1,100 @@
import logging
import os
from logging.config import fileConfig
import sys
from alembic import context
from flask import current_app
from sqlalchemy import engine_from_config, pool
USE_TWOPHASE = False
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config
# Interpret the config file for Python logging.
# This line sets up loggers basically.
fileConfig(config.config_file_name)
logger = logging.getLogger('alembic.env')
# add your model's MetaData object here
# for 'autogenerate' support
# 将当前目录的父目录(api目录)添加到Python路径中,以便能够导入models模块
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
# 获取当前运行的应用数据库引擎和URL
def get_engine():
try:
return current_app.extensions['sqlalchemy'].db.engine
except (KeyError, 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('%', '%%')
# 使用当前应用的数据库URL替换配置文件中的URL
config.set_main_option('sqlalchemy.url', get_engine_url())
from models import db
target_metadata = db.Model.metadata
# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.
def run_migrations_offline():
"""Run migrations in 'offline' mode.
This configures the context with just a URL
and not an Engine, though an Engine is acceptable
here as well. By skipping the Engine creation
we don't even need a DBAPI to be available.
Calls to context.execute() here emit the given string to the
script output.
"""
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
version_table="alembic_version_extend",
)
with context.begin_transaction():
context.run_migrations()
def run_migrations_online():
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
# 使用应用的数据库引擎,而不是从配置文件创建
connectable = get_engine()
with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata,
version_table="alembic_version_extend",
)
with context.begin_transaction():
context.run_migrations()
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
+34
View File
@@ -0,0 +1,34 @@
"""${message}
Revision ID: ${up_revision}
Revises: ${down_revision | comma,n}
Create Date: ${create_date}
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.engine.reflection import Inspector
import models as models
${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():
# ### commands auto generated by Alembic - please adjust! ###
conn = op.get_bind()
inspector = Inspector.from_engine(conn)
tables = inspector.get_table_names()
${upgrades if upgrades else "pass"}
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
${downgrades if downgrades else "pass"}
# ### end Alembic commands ###
@@ -1,33 +1,38 @@
"""recommended list sorted by usage frequency
Revision ID: 06b18b329024
Revises: 9e52f36c2d6d
Revision ID: 001_recommended_list_sorted
Revises:
Create Date: 2024-07-25 14:55:34.357214
"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy.engine.reflection import Inspector
import models as models
# revision identifiers, used by Alembic.
revision = '06b18b329024'
down_revision = '9e52f36c2d6d'
revision = '001_recommended_list_sorted'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('app_statistics_extend',
sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('app_id', models.types.StringUUID(), nullable=False),
sa.Column('number', sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint('id', name='app_statistics_extend_pkey')
)
with op.batch_alter_table('app_statistics_extend', schema=None) as batch_op:
batch_op.create_index('app_statistics_extend_app_id_idx', ['app_id'], unique=False)
conn = op.get_bind()
inspector = Inspector.from_engine(conn)
tables = inspector.get_table_names()
if 'app_statistics_extend' not in tables:
op.create_table('app_statistics_extend',
sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('app_id', models.types.StringUUID(), nullable=False),
sa.Column('number', sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint('id', name='app_statistics_extend_pkey')
)
with op.batch_alter_table('app_statistics_extend', schema=None) as batch_op:
batch_op.create_index('app_statistics_extend_app_id_idx', ['app_id'], unique=False)
# ### end Alembic commands ###
@@ -1,35 +1,41 @@
"""add_account_money_extend
Revision ID: 09633b4cf949
Revises: 59fc25e84ae2
Revision ID: 005_account_money_extend
Revises: 004_ai_billing_forwarding
Create Date: 2024-07-31 09:35:34.164412
"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy.engine.reflection import Inspector
import models as models
from models import db, types
# revision identifiers, used by Alembic.
revision = '09633b4cf949'
down_revision = '59fc25e84ae2'
revision = '005_account_money_extend'
down_revision = '004_ai_billing_forwarding'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('account_money_extend',
sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('account_id', models.types.StringUUID(), nullable=False),
sa.Column('total_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('used_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='account_money_pkey')
)
with op.batch_alter_table('account_money_extend', schema=None) as batch_op:
batch_op.create_index('idx_account_money_account_id', ['account_id'], unique=False)
conn = op.get_bind()
inspector = Inspector.from_engine(conn)
tables = inspector.get_table_names()
if 'account_money_extend' not in tables:
op.create_table('account_money_extend',
sa.Column('id', types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('account_id', types.StringUUID(), nullable=False),
sa.Column('total_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('used_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='account_money_pkey')
)
with op.batch_alter_table('account_money_extend', schema=None) as batch_op:
batch_op.create_index('idx_account_money_account_id', ['account_id'], unique=False)
# ### end Alembic commands ###
@@ -1,37 +1,42 @@
"""add_end_user_account_joins_extend
Revision ID: a6f3333821be
Revises: 09633b4cf949
Revision ID: 006_end_user_account_joins
Revises: 005_account_money_extend
Create Date: 2024-08-03 07:24:13.552085
"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy.engine.reflection import Inspector
import models as models
from models import db, types
# revision identifiers, used by Alembic.
revision = 'a6f3333821be'
down_revision = '09633b4cf949'
revision = '006_end_user_account_joins'
down_revision = '005_account_money_extend'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('end_user_account_joins_extend',
sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('end_user_id', models.types.StringUUID(), nullable=False),
sa.Column('account_id', models.types.StringUUID(), nullable=False),
sa.Column('app_id', models.types.StringUUID(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='end_user_account_joins_pkey')
)
with op.batch_alter_table('end_user_account_joins_extend', schema=None) as batch_op:
batch_op.create_index('end_user_account_joins_account_id_idx', ['account_id'], unique=False)
batch_op.create_index('end_user_account_joins_end_user_id_app_id_idx', ['end_user_id', 'app_id'], unique=False)
conn = op.get_bind()
inspector = Inspector.from_engine(conn)
tables = inspector.get_table_names()
if 'end_user_account_joins_extend' not in tables:
op.create_table('end_user_account_joins_extend',
sa.Column('id', types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('end_user_id', types.StringUUID(), nullable=False),
sa.Column('account_id', types.StringUUID(), nullable=False),
sa.Column('app_id', types.StringUUID(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='end_user_account_joins_pkey')
)
with op.batch_alter_table('end_user_account_joins_extend', schema=None) as batch_op:
batch_op.create_index('end_user_account_joins_account_id_idx', ['account_id'], unique=False)
batch_op.create_index('end_user_account_joins_end_user_id_app_id_idx', ['end_user_id', 'app_id'], unique=False)
# ### end Alembic commands ###
@@ -1,37 +1,42 @@
"""add_account_money_monthly_stat_extend
Revision ID: fb321d6d1ef0
Revises: a6f3333821be
Revision ID: 007_account_money_monthly_stat
Revises: 006_end_user_account_joins
Create Date: 2024-08-05 06:26:05.685901
"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy.engine.reflection import Inspector
import models as models
from models import db, types
# revision identifiers, used by Alembic.
revision = 'fb321d6d1ef0'
down_revision = 'a6f3333821be'
revision = '007_account_money_monthly_stat'
down_revision = '006_end_user_account_joins'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('account_money_monthly_stat_extend',
sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('account_id', models.types.StringUUID(), nullable=False),
sa.Column('total_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('used_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('stat_at', sa.DateTime(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='account_money_monthly_stat_pkey')
)
with op.batch_alter_table('account_money_monthly_stat_extend', schema=None) as batch_op:
batch_op.create_index('idx_account_money_monthly_stat_account_id', ['account_id'], unique=False)
conn = op.get_bind()
inspector = Inspector.from_engine(conn)
tables = inspector.get_table_names()
if 'account_money_monthly_stat_extend' not in tables:
op.create_table('account_money_monthly_stat_extend',
sa.Column('id', types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('account_id', types.StringUUID(), nullable=False),
sa.Column('total_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('used_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('stat_at', sa.DateTime(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='account_money_monthly_stat_pkey')
)
with op.batch_alter_table('account_money_monthly_stat_extend', schema=None) as batch_op:
batch_op.create_index('idx_account_money_monthly_stat_account_id', ['account_id'], unique=False)
# ### end Alembic commands ###
@@ -1,37 +1,42 @@
"""add_account_layover_record_extend
Revision ID: fbd1f511a08e
Revises: 9cb135c9d1f8
Revision ID: 008_account_layover_record
Revises: 007_account_money_monthly_stat
Create Date: 2024-08-27 03:08:09.118504
"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy.engine.reflection import Inspector
import models as models
from models import db, types
# revision identifiers, used by Alembic.
revision = 'fbd1f511a08e'
down_revision = '9cb135c9d1f8'
revision = '008_account_layover_record'
down_revision = '007_account_money_monthly_stat'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('account_layover_record_extend',
sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('account_id', models.types.StringUUID(), nullable=False),
sa.Column('forwarding_id', models.types.StringUUID(), nullable=False),
sa.Column('money', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('info', sa.JSON(), nullable=True),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='account_layover_record_extend_pkey')
)
with op.batch_alter_table('account_layover_record_extend', schema=None) as batch_op:
batch_op.create_index('idx_account_layover_record_account_id', ['account_id'], unique=False)
batch_op.create_index('idx_account_layover_record_forwarding_id', ['forwarding_id'], unique=False)
conn = op.get_bind()
inspector = Inspector.from_engine(conn)
tables = inspector.get_table_names()
if 'account_layover_record_extend' not in tables:
op.create_table('account_layover_record_extend',
sa.Column('id', types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('account_id', types.StringUUID(), nullable=False),
sa.Column('forwarding_id', types.StringUUID(), nullable=False),
sa.Column('money', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('info', sa.JSON(), nullable=True),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='account_layover_record_extend_pkey')
)
with op.batch_alter_table('account_layover_record_extend', schema=None) as batch_op:
batch_op.create_index('idx_account_layover_record_account_id', ['account_id'], unique=False)
batch_op.create_index('idx_account_layover_record_forwarding_id', ['forwarding_id'], unique=False)
# ### end Alembic commands ###
@@ -1,82 +1,90 @@
"""add_api_token_money_extend
Revision ID: 1b804f8bbd28
Revises: fbd1f511a08e
Revision ID: 009_api_token_money_extend
Revises: 008_account_layover_record
Create Date: 2024-08-29 07:15:02.913278
"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy.engine.reflection import Inspector
import models as models
from models import db, types
# revision identifiers, used by Alembic.
revision = '1b804f8bbd28'
down_revision = 'fbd1f511a08e'
revision = '009_api_token_money_extend'
down_revision = '008_account_layover_record'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('api_token_message_joins_extend',
sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('app_token_id', models.types.StringUUID(), nullable=True),
sa.Column('record_id', models.types.StringUUID(), nullable=True),
sa.Column('app_mode', sa.String(length=255), nullable=True),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='api_token_message_joins_extend_pkey')
)
with op.batch_alter_table('api_token_message_joins_extend', schema=None) as batch_op:
batch_op.create_index('api_token_message_joins_extend_app_token_id_idx', ['app_token_id'], unique=False)
batch_op.create_index('api_token_message_joins_extend_record_id_idx', ['record_id'], unique=False)
conn = op.get_bind()
inspector = Inspector.from_engine(conn)
tables = inspector.get_table_names()
if 'api_token_message_joins_extend' not in tables:
op.create_table('api_token_message_joins_extend',
sa.Column('id', types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('app_token_id', types.StringUUID(), nullable=True),
sa.Column('record_id', types.StringUUID(), nullable=True),
sa.Column('app_mode', sa.String(length=255), nullable=True),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='api_token_message_joins_extend_pkey')
)
with op.batch_alter_table('api_token_message_joins_extend', schema=None) as batch_op:
batch_op.create_index('api_token_message_joins_extend_app_token_id_idx', ['app_token_id'], unique=False)
batch_op.create_index('api_token_message_joins_extend_record_id_idx', ['record_id'], unique=False)
op.create_table('api_token_money_daily_stat_extend',
sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('app_token_id', models.types.StringUUID(), nullable=False),
sa.Column('accumulated_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('day_used_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('day_limit_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('stat_at', sa.DateTime(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='api_token_money_daily_stat_pkey')
)
with op.batch_alter_table('api_token_money_daily_stat_extend', schema=None) as batch_op:
batch_op.create_index('idx_api_token_money_daily_stat_app_token_id', ['app_token_id'], unique=False)
if 'api_token_money_daily_stat_extend' not in tables:
op.create_table('api_token_money_daily_stat_extend',
sa.Column('id', types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('app_token_id', types.StringUUID(), nullable=False),
sa.Column('accumulated_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('day_used_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('day_limit_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('stat_at', sa.DateTime(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='api_token_money_daily_stat_pkey')
)
with op.batch_alter_table('api_token_money_daily_stat_extend', schema=None) as batch_op:
batch_op.create_index('idx_api_token_money_daily_stat_app_token_id', ['app_token_id'], unique=False)
op.create_table('api_token_money_extend',
sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('app_token_id', models.types.StringUUID(), nullable=True),
sa.Column('accumulated_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('day_used_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('month_used_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('day_limit_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('month_limit_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('is_deleted', sa.Boolean(), server_default=sa.text('false'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('description', sa.String(length=50), nullable=True),
sa.PrimaryKeyConstraint('id', name='api_token_money_extend_pkey')
)
with op.batch_alter_table('api_token_money_extend', schema=None) as batch_op:
batch_op.create_index('api_tokens_money_app_token_id_idx', ['app_token_id'], unique=False)
op.create_table('api_token_money_monthly_stat_extend',
sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('app_token_id', models.types.StringUUID(), nullable=False),
sa.Column('accumulated_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('month_used_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('month_limit_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('stat_at', sa.DateTime(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='api_token_money_monthly_stat_pkey')
)
with op.batch_alter_table('api_token_money_monthly_stat_extend', schema=None) as batch_op:
batch_op.create_index('idx_api_token_money_monthly_stat_app_token_id', ['app_token_id'], unique=False)
if 'api_token_money_extend' not in tables:
op.create_table('api_token_money_extend',
sa.Column('id', types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('app_token_id', types.StringUUID(), nullable=True),
sa.Column('accumulated_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('day_used_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('month_used_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('day_limit_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('month_limit_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('is_deleted', sa.Boolean(), server_default=sa.text('false'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('description', sa.String(length=50), nullable=True),
sa.PrimaryKeyConstraint('id', name='api_token_money_extend_pkey')
)
with op.batch_alter_table('api_token_money_extend', schema=None) as batch_op:
batch_op.create_index('api_tokens_money_app_token_id_idx', ['app_token_id'], unique=False)
if 'api_token_money_monthly_stat_extend' not in tables:
op.create_table('api_token_money_monthly_stat_extend',
sa.Column('id', types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('app_token_id', types.StringUUID(), nullable=False),
sa.Column('accumulated_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('month_used_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('month_limit_quota', sa.Numeric(precision=16, scale=7), nullable=True),
sa.Column('stat_at', sa.DateTime(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='api_token_money_monthly_stat_pkey')
)
with op.batch_alter_table('api_token_money_monthly_stat_extend', schema=None) as batch_op:
batch_op.create_index('idx_api_token_money_monthly_stat_app_token_id', ['app_token_id'], unique=False)
# ### end Alembic commands ###
@@ -1,36 +1,42 @@
"""add_system_integration_extend
Revision ID: 588f1696997b
Revises: 37e5bf7a1e53
Revision ID: 010_system_integration_extend
Revises: 009_api_token_money_extend
Create Date: 2025-03-31 21:36:03.818117
"""
from alembic import op
import models as models
from models import db, types
import sqlalchemy as sa
from sqlalchemy.engine.reflection import Inspector
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '588f1696997b'
down_revision = '37e5bf7a1e53'
revision = '010_system_integration_extend'
down_revision = '009_api_token_money_extend'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('system_integration_extend',
sa.Column('id', sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column('classify', sa.Integer(), server_default=sa.text('1'), nullable=False),
sa.Column('status', sa.Boolean(), server_default=sa.text('false'), nullable=False),
sa.Column('corp_id', sa.String(length=120), nullable=True),
sa.Column('agent_id', sa.String(length=120), nullable=True),
sa.Column('app_key', sa.String(length=120), nullable=True),
sa.Column('app_secret', sa.Text(), nullable=True),
sa.PrimaryKeyConstraint('id', name='system_integration_joins_pkey')
)
with op.batch_alter_table('system_integration_extend', schema=None) as batch_op:
batch_op.create_index('system_integration_joins_classify_idx', ['classify'], unique=False)
conn = op.get_bind()
inspector = Inspector.from_engine(conn)
tables = inspector.get_table_names()
if 'system_integration_extend' not in tables:
op.create_table('system_integration_extend',
sa.Column('id', sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column('classify', sa.Integer(), server_default=sa.text('1'), nullable=False),
sa.Column('status', sa.Boolean(), server_default=sa.text('false'), nullable=False),
sa.Column('corp_id', sa.String(length=120), nullable=True),
sa.Column('agent_id', sa.String(length=120), nullable=True),
sa.Column('app_key', sa.String(length=120), nullable=True),
sa.Column('app_secret', sa.Text(), nullable=True),
sa.PrimaryKeyConstraint('id', name='system_integration_joins_pkey')
)
with op.batch_alter_table('system_integration_extend', schema=None) as batch_op:
batch_op.create_index('system_integration_joins_classify_idx', ['classify'], unique=False)
# ### end Alembic commands ###
@@ -1,44 +1,50 @@
"""add_recommended_apps_category_join_extend
Revision ID: 41e6e402d572
Revises: 408176b91ad3
Revision ID: 002_recommended_apps_category
Revises: 001_recommended_list_sorted
Create Date: 2024-07-18 06:38:49.622100
"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy.engine.reflection import Inspector
import models as models
from models import db, types
# revision identifiers, used by Alembic.
revision = '41e6e402d572'
down_revision = '408176b91ad3'
revision = '002_recommended_apps_category'
down_revision = '001_recommended_list_sorted'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('recommended_apps_category_join_extend',
sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('recommended_id', models.types.StringUUID(), nullable=False),
sa.Column('category_id', models.types.StringUUID(), nullable=False),
sa.PrimaryKeyConstraint('id', name='recommended_apps_category_id_pkey')
)
with op.batch_alter_table('recommended_apps_category_join_extend', schema=None) as batch_op:
batch_op.create_index('idx_recommended_category_id', ['category_id'], unique=False)
batch_op.create_index('idx_recommended_id', ['recommended_id'], unique=False)
op.create_table('recommended_category_extend',
sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('table', sa.String(length=255), nullable=False),
sa.Column('tag_id', models.types.StringUUID(), nullable=True),
sa.PrimaryKeyConstraint('id', name='category_extend_id_pkey')
)
with op.batch_alter_table('recommended_category_extend', schema=None) as batch_op:
batch_op.create_index('idx_extend_table', ['table'], unique=False)
batch_op.create_index('idx_extend_tag_bind_tag_id', ['tag_id'], unique=False)
conn = op.get_bind()
inspector = Inspector.from_engine(conn)
tables = inspector.get_table_names()
if 'recommended_apps_category_join_extend' not in tables:
op.create_table('recommended_apps_category_join_extend',
sa.Column('id', types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('recommended_id', types.StringUUID(), nullable=False),
sa.Column('category_id', types.StringUUID(), nullable=False),
sa.PrimaryKeyConstraint('id', name='recommended_apps_category_id_pkey')
)
with op.batch_alter_table('recommended_apps_category_join_extend', schema=None) as batch_op:
batch_op.create_index('idx_recommended_category_id', ['category_id'], unique=False)
batch_op.create_index('idx_recommended_id', ['recommended_id'], unique=False)
if 'recommended_category_extend' not in tables:
op.create_table('recommended_category_extend',
sa.Column('id', types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('table', sa.String(length=255), nullable=False),
sa.Column('tag_id', types.StringUUID(), nullable=True),
sa.PrimaryKeyConstraint('id', name='category_extend_id_pkey')
)
with op.batch_alter_table('recommended_category_extend', schema=None) as batch_op:
batch_op.create_index('idx_extend_table', ['table'], unique=False)
batch_op.create_index('idx_extend_tag_bind_tag_id', ['tag_id'], unique=False)
# ### end Alembic commands ###
@@ -1,51 +1,57 @@
"""ai billing and forwarding two extend
Revision ID: 9e52f36c2d6d
Revises: d8929f29057c
Revision ID: 004_ai_billing_forwarding
Revises: 003_tenant_model_sync_extend
Create Date: 2024-07-23 19:27:09.150306
"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy.engine.reflection import Inspector
import models as models
from models import db, types
# revision identifiers, used by Alembic.
revision = '9e52f36c2d6d'
down_revision = 'd8929f29057c'
revision = '004_ai_billing_forwarding'
down_revision = '003_tenant_model_sync_extend'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('forwarding_address_extend',
sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('forwarding_id', models.types.StringUUID(), nullable=False),
sa.Column('path', sa.String(length=255), nullable=False),
sa.Column('models', sa.String(length=255), nullable=False),
sa.Column('description', sa.Text(), server_default=sa.text("''::character varying"), nullable=False),
sa.Column('content_type', sa.Integer(), server_default=sa.text('0'), nullable=False),
sa.Column('billing', sa.Text(), server_default=sa.text("'[]'"), nullable=False),
sa.Column('status', sa.Boolean(), server_default=sa.text('true'), nullable=True),
sa.PrimaryKeyConstraint('id', name='forwarding_address_pkey')
)
with op.batch_alter_table('forwarding_address_extend', schema=None) as batch_op:
batch_op.create_index('idx_forwarding_address_id', ['forwarding_id'], unique=False)
batch_op.create_index('idx_forwarding_address_path', ['path'], unique=False)
batch_op.create_index('idx_forwarding_address_status', ['status'], unique=False)
op.create_table('forwarding_extend',
sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('path', sa.String(length=255), nullable=False),
sa.Column('address', sa.String(length=255), nullable=False),
sa.Column('header', sa.Text(), server_default=sa.text("'[]'"), nullable=False),
sa.Column('description', sa.Text(), server_default=sa.text("''::character varying"), nullable=False),
sa.PrimaryKeyConstraint('id', name='forwarding_extend_pkey')
)
with op.batch_alter_table('forwarding_extend', schema=None) as batch_op:
batch_op.create_index('idx_forwarding_path', ['path'], unique=False)
conn = op.get_bind()
inspector = Inspector.from_engine(conn)
tables = inspector.get_table_names()
if 'forwarding_address_extend' not in tables:
op.create_table('forwarding_address_extend',
sa.Column('id', types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('forwarding_id', types.StringUUID(), nullable=False),
sa.Column('path', sa.String(length=255), nullable=False),
sa.Column('models', sa.String(length=255), nullable=False),
sa.Column('description', sa.Text(), server_default=sa.text("''::character varying"), nullable=False),
sa.Column('content_type', sa.Integer(), server_default=sa.text('0'), nullable=False),
sa.Column('billing', sa.Text(), server_default=sa.text("'[]'"), nullable=False),
sa.Column('status', sa.Boolean(), server_default=sa.text('true'), nullable=True),
sa.PrimaryKeyConstraint('id', name='forwarding_address_pkey')
)
with op.batch_alter_table('forwarding_address_extend', schema=None) as batch_op:
batch_op.create_index('idx_forwarding_address_id', ['forwarding_id'], unique=False)
batch_op.create_index('idx_forwarding_address_path', ['path'], unique=False)
batch_op.create_index('idx_forwarding_address_status', ['status'], unique=False)
if 'forwarding_extend' not in tables:
op.create_table('forwarding_extend',
sa.Column('id', types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('path', sa.String(length=255), nullable=False),
sa.Column('address', sa.String(length=255), nullable=False),
sa.Column('header', sa.Text(), server_default=sa.text("'[]'"), nullable=False),
sa.Column('description', sa.Text(), server_default=sa.text("''::character varying"), nullable=False),
sa.PrimaryKeyConstraint('id', name='forwarding_extend_pkey')
)
with op.batch_alter_table('forwarding_extend', schema=None) as batch_op:
batch_op.create_index('idx_forwarding_path', ['path'], unique=False)
# ### end Alembic commands ###
@@ -1,47 +1,54 @@
"""add_tenant_model_sync_extend
Revision ID: d8929f29057c
Revises: 41e6e402d572
Revision ID: 003_tenant_model_sync_extend
Revises: 002_recommended_apps_category
Create Date: 2024-07-22 12:17:28.093253
"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy.engine.reflection import Inspector
import models as models
from models import db, types
# revision identifiers, used by Alembic.
revision = 'd8929f29057c'
down_revision = '41e6e402d572'
revision = '003_tenant_model_sync_extend'
down_revision = '002_recommended_apps_category'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('model_sync_config_extend',
sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('model_id', models.types.StringUUID(), nullable=True),
sa.Column('is_all', sa.Boolean(), server_default=sa.text('true'), nullable=True),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='model_sync_config_extend_pkey'),
sa.UniqueConstraint('model_id', name='unique_model_id')
)
op.create_table('tenant_model_sync_extend',
sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('tenant_id', models.types.StringUUID(), nullable=False),
sa.Column('model_id', models.types.StringUUID(), nullable=False),
sa.Column('origin_model_id', sa.String(length=255), nullable=False),
sa.Column('is_all', sa.Boolean(), server_default=sa.text('false'), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='tenant_model_sync_extend_pkey')
)
with op.batch_alter_table('tenant_model_sync_extend', schema=None) as batch_op:
batch_op.create_index('tenant_model_sync_extend_model_idx', ['model_id'], unique=False)
batch_op.create_index('tenant_model_sync_extend_tenant_idx', ['tenant_id'], unique=False)
conn = op.get_bind()
inspector = Inspector.from_engine(conn)
tables = inspector.get_table_names()
if 'model_sync_config_extend' not in tables:
op.create_table('model_sync_config_extend',
sa.Column('id', types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('model_id', types.StringUUID(), nullable=True),
sa.Column('is_all', sa.Boolean(), server_default=sa.text('true'), nullable=True),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='model_sync_config_extend_pkey'),
sa.UniqueConstraint('model_id', name='unique_model_id')
)
if 'tenant_model_sync_extend' not in tables:
op.create_table('tenant_model_sync_extend',
sa.Column('id', types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('tenant_id', types.StringUUID(), nullable=False),
sa.Column('model_id', types.StringUUID(), nullable=False),
sa.Column('origin_model_id', sa.String(length=255), nullable=False),
sa.Column('is_all', sa.Boolean(), server_default=sa.text('false'), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False),
sa.PrimaryKeyConstraint('id', name='tenant_model_sync_extend_pkey')
)
with op.batch_alter_table('tenant_model_sync_extend', schema=None) as batch_op:
batch_op.create_index('tenant_model_sync_extend_model_idx', ['model_id'], unique=False)
batch_op.create_index('tenant_model_sync_extend_tenant_idx', ['tenant_id'], unique=False)
# ### end Alembic commands ###