mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-26 01:01:52 +08:00
commit
a70463b961
File diff suppressed because it is too large
Load Diff
@ -5,10 +5,19 @@
|
|||||||
|
|
||||||
Target Server Type : PostgreSQL
|
Target Server Type : PostgreSQL
|
||||||
|
|
||||||
Date: 2024-05-01 23:25:45
|
Date: 2024-05-03 23:36:19
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for dual
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS dual;
|
||||||
|
CREATE TABLE dual
|
||||||
|
(
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for infra_api_access_log
|
-- Table structure for infra_api_access_log
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@ -3866,7 +3875,6 @@ COMMENT ON COLUMN system_sms_code.updater IS '更新者';
|
|||||||
COMMENT ON COLUMN system_sms_code.update_time IS '更新时间';
|
COMMENT ON COLUMN system_sms_code.update_time IS '更新时间';
|
||||||
COMMENT ON COLUMN system_sms_code.deleted IS '是否删除';
|
COMMENT ON COLUMN system_sms_code.deleted IS '是否删除';
|
||||||
COMMENT ON COLUMN system_sms_code.tenant_id IS '租户编号';
|
COMMENT ON COLUMN system_sms_code.tenant_id IS '租户编号';
|
||||||
COMMENT ON COLUMN system_sms_code.idx_mobile IS '手机号';
|
|
||||||
COMMENT ON TABLE system_sms_code IS '手机验证码';
|
COMMENT ON TABLE system_sms_code IS '手机验证码';
|
||||||
|
|
||||||
DROP SEQUENCE IF EXISTS system_sms_code_seq;
|
DROP SEQUENCE IF EXISTS system_sms_code_seq;
|
||||||
@ -4703,3 +4711,4 @@ COMMIT;
|
|||||||
DROP SEQUENCE IF EXISTS yudao_demo03_student_seq;
|
DROP SEQUENCE IF EXISTS yudao_demo03_student_seq;
|
||||||
CREATE SEQUENCE yudao_demo03_student_seq
|
CREATE SEQUENCE yudao_demo03_student_seq
|
||||||
START 10;
|
START 10;
|
||||||
|
|
||||||
|
@ -5,10 +5,29 @@
|
|||||||
|
|
||||||
Target Server Type : Microsoft SQL Server
|
Target Server Type : Microsoft SQL Server
|
||||||
|
|
||||||
Date: 2024-05-02 15:29:31
|
Date: 2024-05-03 23:36:38
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for dual
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS dual
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE TABLE dual
|
||||||
|
(
|
||||||
|
id int NULL
|
||||||
|
)
|
||||||
|
GO
|
||||||
|
|
||||||
|
EXEC sp_addextendedproperty
|
||||||
|
'MS_Description', N'数据库连接的表',
|
||||||
|
'SCHEMA', N'dbo',
|
||||||
|
'TABLE', N'dual'
|
||||||
|
GO
|
||||||
|
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for infra_api_access_log
|
-- Table structure for infra_api_access_log
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
@ -42,9 +42,36 @@ docker compose exec sqlserver bash /tmp/create_schema.sh
|
|||||||
|
|
||||||
### 1.5 DM 达梦
|
### 1.5 DM 达梦
|
||||||
|
|
||||||
TODO 暂未支持
|
下载达梦docker镜像 https://download.dameng.com/eco/dm8/dm8_20230808_rev197096_x86_rh6_64_single.tar
|
||||||
|
|
||||||
## 2. MySQL 转换其它数据库
|
加载镜像文件,在镜像tar文件所在目录运行:
|
||||||
|
|
||||||
|
```Bash
|
||||||
|
docker load -i dm8_20230808_rev197096_x86_rh6_64_single.tar
|
||||||
|
````
|
||||||
|
在项目`sql/tools`目录下运行:
|
||||||
|
|
||||||
|
```Bash
|
||||||
|
docker compose up -d dm8
|
||||||
|
# 注意:启动完 sqlserver 后,需要手动再执行如下命令,因为 SQL Server 不支持初始化脚本
|
||||||
|
docker compose exec dm8 bash -c "exec /opt/dmdbms/bin/disql SYSDBA/SYSDBA001 \`/tmp/schema.sql"
|
||||||
|
exit
|
||||||
|
```
|
||||||
|
|
||||||
|
**注意**: `sql/dm/ruoyi-vue-pro-dm8.sql`文件编码必须为`GBK`或者`GBK`超集
|
||||||
|
|
||||||
|
暂不支持 MacBook Apple Silicon,因为 达梦 官方没有提供 Apple Silicon 版本的 Docker 镜像。
|
||||||
|
|
||||||
|
## 2. 测试数据库docker容器的销毁重建
|
||||||
|
|
||||||
|
开发测试过程中,有时候需要创建全新干净的数据库。由于测试数据docker容器采用数据卷(volume)挂载数据库实例的数据目录,因此销毁数据需要停止容器后,删除数据卷,然后再重新创建容器。以postgres为例,操作如下:
|
||||||
|
|
||||||
|
```Bash
|
||||||
|
docker compose down postgres
|
||||||
|
docker volume rm ruoyi-vue-pro_postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. MySQL 转换其它数据库
|
||||||
|
|
||||||
### 2.1 实现原理
|
### 2.1 实现原理
|
||||||
|
|
||||||
|
@ -134,6 +134,14 @@ class Convertor(ABC):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def gen_dual(self) -> str:
|
||||||
|
"""生成虚拟 dual 表
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: 生成脚本, 默认返回空脚本, 表示当前数据库无需手工创建
|
||||||
|
"""
|
||||||
|
return ""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def inserts(table_name: str, script_content: str) -> Generator:
|
def inserts(table_name: str, script_content: str) -> Generator:
|
||||||
PREFIX = f"INSERT INTO `{table_name}`"
|
PREFIX = f"INSERT INTO `{table_name}`"
|
||||||
@ -192,6 +200,17 @@ class Convertor(ABC):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
dual = self.gen_dual()
|
||||||
|
if dual:
|
||||||
|
print(
|
||||||
|
f"""-- ----------------------------
|
||||||
|
-- Table structure for dual
|
||||||
|
-- ----------------------------
|
||||||
|
{dual}
|
||||||
|
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
error_scripts = []
|
error_scripts = []
|
||||||
for table_sql in self.table_script_list:
|
for table_sql in self.table_script_list:
|
||||||
ddl = DDLParser(table_sql.replace("`", "")).run()
|
ddl = DDLParser(table_sql.replace("`", "")).run()
|
||||||
@ -348,6 +367,12 @@ CREATE SEQUENCE {table_name}_seq
|
|||||||
|
|
||||||
return script
|
return script
|
||||||
|
|
||||||
|
def gen_dual(self) -> str:
|
||||||
|
return """DROP TABLE IF EXISTS dual;
|
||||||
|
CREATE TABLE dual
|
||||||
|
(
|
||||||
|
);"""
|
||||||
|
|
||||||
|
|
||||||
class OracleConvertor(Convertor):
|
class OracleConvertor(Convertor):
|
||||||
def __init__(self, src):
|
def __init__(self, src):
|
||||||
@ -571,7 +596,7 @@ GO
|
|||||||
return "\n".join(f"{script}\nGO" for script in self.index(ddl))
|
return "\n".join(f"{script}\nGO" for script in self.index(ddl))
|
||||||
|
|
||||||
def gen_insert(self, table_name: str) -> str:
|
def gen_insert(self, table_name: str) -> str:
|
||||||
"""生成 insert 语句,以及根据最后的 insert id+1 生成 Sequence"""
|
"""生成 insert 语句"""
|
||||||
|
|
||||||
# 收集 `table_name` 对应的 insert 语句
|
# 收集 `table_name` 对应的 insert 语句
|
||||||
inserts = []
|
inserts = []
|
||||||
@ -601,6 +626,126 @@ SET IDENTITY_INSERT {table_name.lower()} OFF
|
|||||||
GO
|
GO
|
||||||
COMMIT
|
COMMIT
|
||||||
GO
|
GO
|
||||||
|
-- @formatter:on"""
|
||||||
|
|
||||||
|
return script
|
||||||
|
|
||||||
|
def gen_dual(self) -> str:
|
||||||
|
return """DROP TABLE IF EXISTS dual
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE TABLE dual
|
||||||
|
(
|
||||||
|
id int NULL
|
||||||
|
)
|
||||||
|
GO
|
||||||
|
|
||||||
|
EXEC sp_addextendedproperty
|
||||||
|
'MS_Description', N'数据库连接的表',
|
||||||
|
'SCHEMA', N'dbo',
|
||||||
|
'TABLE', N'dual'
|
||||||
|
GO"""
|
||||||
|
|
||||||
|
|
||||||
|
class DM8Convertor(Convertor):
|
||||||
|
def __init__(self, src):
|
||||||
|
super().__init__(src, "DM8")
|
||||||
|
|
||||||
|
def translate_type(self, type: str, size: Optional[Union[int, Tuple[int]]]):
|
||||||
|
"""类型转换"""
|
||||||
|
type = type.lower()
|
||||||
|
|
||||||
|
if type == "varchar":
|
||||||
|
return f"varchar({size})"
|
||||||
|
if type == "int":
|
||||||
|
return "int"
|
||||||
|
if type == "bigint" or type == "bigint unsigned":
|
||||||
|
return "bigint"
|
||||||
|
if type == "datetime":
|
||||||
|
return "datetime"
|
||||||
|
if type == "bit":
|
||||||
|
return "bit"
|
||||||
|
if type in ("tinyint", "smallint"):
|
||||||
|
return "smallint"
|
||||||
|
if type == "text":
|
||||||
|
return "text"
|
||||||
|
if type == "blob":
|
||||||
|
return "blob"
|
||||||
|
if type == "mediumblob":
|
||||||
|
return "varchar(10240)"
|
||||||
|
if type == "decimal":
|
||||||
|
return (
|
||||||
|
f"decimal({','.join(str(s) for s in size)})" if len(size) else "decimal"
|
||||||
|
)
|
||||||
|
|
||||||
|
def gen_create(self, ddl) -> str:
|
||||||
|
"""生成 CREATE 语句"""
|
||||||
|
|
||||||
|
def generate_column(col):
|
||||||
|
name = col["name"].lower()
|
||||||
|
if name == "id":
|
||||||
|
return "id bigint NOT NULL PRIMARY KEY IDENTITY"
|
||||||
|
|
||||||
|
type = col["type"].lower()
|
||||||
|
full_type = self.translate_type(type, col["size"])
|
||||||
|
nullable = "NULL" if col["nullable"] else "NOT NULL"
|
||||||
|
default = f"DEFAULT {col['default']}" if col["default"] is not None else ""
|
||||||
|
return f"{name} {full_type} {default} {nullable}"
|
||||||
|
|
||||||
|
table_name = ddl["table_name"].lower()
|
||||||
|
columns = [f"{generate_column(col).strip()}" for col in ddl["columns"]]
|
||||||
|
field_def_list = ",\n ".join(columns)
|
||||||
|
script = f"""-- ----------------------------
|
||||||
|
-- Table structure for {table_name}
|
||||||
|
-- ----------------------------
|
||||||
|
CREATE TABLE {table_name} (
|
||||||
|
{field_def_list}
|
||||||
|
);"""
|
||||||
|
|
||||||
|
# oracle INSERT '' 不能通过 NOT NULL 校验
|
||||||
|
script = script.replace("DEFAULT '' NOT NULL", "DEFAULT '' NULL")
|
||||||
|
|
||||||
|
return script
|
||||||
|
|
||||||
|
def gen_index(self, ddl: Dict) -> str:
|
||||||
|
return "\n".join(f"{script};" for script in self.index(ddl))
|
||||||
|
|
||||||
|
def gen_comment(self, table_sql: str, table_name: str) -> str:
|
||||||
|
script = ""
|
||||||
|
for field, comment_string in self.filed_comments(table_sql):
|
||||||
|
script += (
|
||||||
|
f"COMMENT ON COLUMN {table_name}.{field} IS '{comment_string}';" + "\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
table_comment = self.table_comment(table_sql)
|
||||||
|
if table_comment:
|
||||||
|
script += f"COMMENT ON TABLE {table_name} IS '{table_comment}';\n"
|
||||||
|
|
||||||
|
return script
|
||||||
|
|
||||||
|
def gen_pk(self, table_name: str) -> str:
|
||||||
|
"""生成主键定义"""
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def gen_index(self, ddl: Dict) -> str:
|
||||||
|
return "\n".join(f"{script};" for script in self.index(ddl))
|
||||||
|
|
||||||
|
def gen_insert(self, table_name: str) -> str:
|
||||||
|
"""拷贝 INSERT 语句"""
|
||||||
|
inserts = list(Convertor.inserts(table_name, self.content))
|
||||||
|
|
||||||
|
## 生成 insert 脚本
|
||||||
|
script = ""
|
||||||
|
if inserts:
|
||||||
|
inserts_lines = "\n".join(inserts)
|
||||||
|
script += f"""\n\n-- ----------------------------
|
||||||
|
-- Records of {table_name.lower()}
|
||||||
|
-- ----------------------------
|
||||||
|
-- @formatter:off
|
||||||
|
SET IDENTITY_INSERT {table_name.lower()} ON;
|
||||||
|
{inserts_lines}
|
||||||
|
COMMIT;
|
||||||
|
SET IDENTITY_INSERT {table_name.lower()} OFF;
|
||||||
-- @formatter:on"""
|
-- @formatter:on"""
|
||||||
|
|
||||||
return script
|
return script
|
||||||
@ -612,7 +757,7 @@ def main():
|
|||||||
"type",
|
"type",
|
||||||
type=str,
|
type=str,
|
||||||
help="目标数据库类型",
|
help="目标数据库类型",
|
||||||
choices=["postgres", "oracle", "sqlserver"],
|
choices=["postgres", "oracle", "sqlserver", "dm8"],
|
||||||
)
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
@ -624,6 +769,8 @@ def main():
|
|||||||
convertor = OracleConvertor(sql_file)
|
convertor = OracleConvertor(sql_file)
|
||||||
elif args.type == "sqlserver":
|
elif args.type == "sqlserver":
|
||||||
convertor = SQLServerConvertor(sql_file)
|
convertor = SQLServerConvertor(sql_file)
|
||||||
|
elif args.type == "dm8":
|
||||||
|
convertor = DM8Convertor(sql_file)
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError(f"不支持目标数据库类型: {args.type}")
|
raise NotImplementedError(f"不支持目标数据库类型: {args.type}")
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ volumes:
|
|||||||
mysql: { }
|
mysql: { }
|
||||||
postgres: { }
|
postgres: { }
|
||||||
sqlserver: { }
|
sqlserver: { }
|
||||||
|
dm8: { }
|
||||||
|
|
||||||
services:
|
services:
|
||||||
mysql:
|
mysql:
|
||||||
@ -69,3 +70,25 @@ services:
|
|||||||
- ../sqlserver/ruoyi-vue-pro.sql:/tmp/schema.sql:ro
|
- ../sqlserver/ruoyi-vue-pro.sql:/tmp/schema.sql:ro
|
||||||
# docker compose exec sqlserver bash /tmp/create_schema.sh
|
# docker compose exec sqlserver bash /tmp/create_schema.sh
|
||||||
- ./sqlserver/create_schema.sh:/tmp/create_schema.sh:ro
|
- ./sqlserver/create_schema.sh:/tmp/create_schema.sh:ro
|
||||||
|
|
||||||
|
|
||||||
|
dm8:
|
||||||
|
# wget https://download.dameng.com/eco/dm8/dm8_20230808_rev197096_x86_rh6_64_single.tar
|
||||||
|
# docker load -i dm8_20230808_rev197096_x86_rh6_64_single.tar
|
||||||
|
image: dm8_single:dm8_20230808_rev197096_x86_rh6_64
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
PAGE_SIZE: 16
|
||||||
|
LD_LIBRARY_PATH: /opt/dmdbms/bin
|
||||||
|
EXTENT_SIZE: 32
|
||||||
|
BLANK_PAD_MODE: 1
|
||||||
|
LOG_SIZE: 1024
|
||||||
|
UNICODE_FLAG: 1
|
||||||
|
LENGTH_IN_CHAR: 1
|
||||||
|
INSTANCE_NAME: dm8_test
|
||||||
|
ports:
|
||||||
|
- "5236:5236"
|
||||||
|
volumes:
|
||||||
|
- dm8:/opt/dmdbms/data
|
||||||
|
- ../dm/ruoyi-vue-pro-dm8.sql:/tmp/schema.sql:ro
|
||||||
|
# docker compose exec dm8 bash -c "exec /opt/dmdbms/bin/disql SYSDBA/SYSDBA001 \`/tmp/schema.sql"
|
||||||
|
@ -50,14 +50,14 @@ spring:
|
|||||||
# url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
|
# url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
|
||||||
# url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true # PostgreSQL 连接的示例
|
# url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true # PostgreSQL 连接的示例
|
||||||
# url: jdbc:oracle:thin:@//127.0.0.1:1521/XEPDB1 # Oracle 连接的示例
|
# url: jdbc:oracle:thin:@//127.0.0.1:1521/XEPDB1 # Oracle 连接的示例
|
||||||
url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8 # SQLServer 连接的示例
|
# url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8 # SQLServer 连接的示例
|
||||||
# url: jdbc:dm://10.211.55.4:5236?schema=RUOYI_VUE_PRO # DM 连接的示例
|
url: jdbc:dm://localhost:5236 # DM 连接的示例
|
||||||
# username: root
|
# username: root
|
||||||
# password: 123456
|
# password: 123456
|
||||||
username: sa # SQLServer 连接的示例
|
# username: sa # SQLServer 连接的示例
|
||||||
password: Yudao@2024 # SQLServer 连接的示例
|
# password: Yudao@2024 # SQLServer 连接的示例
|
||||||
# username: SYSDBA # DM 连接的示例
|
username: SYSDBA # DM 连接的示例
|
||||||
# password: SYSDBA # DM 连接的示例
|
password: SYSDBA001 # DM 连接的示例
|
||||||
slave: # 模拟从库,可根据自己需要修改
|
slave: # 模拟从库,可根据自己需要修改
|
||||||
lazy: true # 开启懒加载,保证启动速度
|
lazy: true # 开启懒加载,保证启动速度
|
||||||
# url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
|
# url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
|
||||||
|
Loading…
Reference in New Issue
Block a user