MySQL表结构转换为ES索引Mapping

背景

日常开发过程中肯定会存在MySQL表数据迁移至ES的情况,以canal为例,数据迁移时需要提前在ES中创建索引Mapping,但是如果碰到字段特别的表时,创建Mapping将是一件耗费心神的事情。为了解决这些重复工作,我使用Python编写了一个脚本,自动将MySQL中的表结构同步到ES中,本脚本只同步表结构,并不同步表数据,如需同步数据可以采用canal或者logstash等方式进行同步

脚本内容

如果不需要直接同步到es中,需要注释脚本最后一行,该脚本会将转换后的mapping信息打印到控制台中

python 复制代码
import mysql.connector
import requests
import json

# MySQL连接配置
mysql_config = {
    'host': '127.0.0.1',
    'port': '3306',
    'user': 'root',
    'password': '123456',
    'database': 'test'
}

# Elasticsearch配置
es_host = '127.0.0.1'
es_port = '9200'
es_index = 'order1'


# 新版本es不需求type字段
# es_type = '_doc'

def fetch_mysql_table_fields(mysql_config):
    connection = mysql.connector.connect(**mysql_config)
    cursor = connection.cursor()

    # 获取MySQL表字段信息,指定需要转换得表名
    cursor.execute(f"DESCRIBE {"`order`"}")
    fields = cursor.fetchall()

    cursor.close()
    connection.close()

    return fields


def generate_es_mapping(fields):
    mapping = {
        "mappings": {
            "properties": {}
        }
    }

    for field in fields:
        field_name = field[0]
        field_type = field[1]

        # 根据MySQL字段类型设置Elasticsearch映射类型
        es_field_type = "text"  # 默认为文本类型
        if "int" in field_type:
            es_field_type = "integer"
        elif "bigint" in field_type:
            es_field_type = "long"
        elif "tinyint" in field_type:
            es_field_type = "short"
        elif "float" in field_type:
            es_field_type = "float"
        elif "double" in field_type:
            es_field_type = "double"
        elif "decimal" in field_type:
            es_field_type = "double"
        elif "date" in field_type or "datetime" in field_type or "timestamp" in field_type or "time" in field_type:
            es_field_type = "date"
        elif "json" in field_type:
            es_field_type = "object"

        # 这里可以根据需要添加更多类型的映射

        mapping["mappings"]["properties"][field_name] = {
            "type": es_field_type
        }

    return mapping


def print_es_mapping(mapping):
    print(json.dumps(mapping, indent=2))


def create_es_index_mapping(es_host, es_port, es_index, mapping):
    url = f"http://{es_host}:{es_port}/{es_index}"
    headers = {'Content-Type': 'application/json'}
    payload = json.dumps(mapping)

    response = requests.put(url, headers=headers, data=payload)

    if response.status_code == 200:
        print(f"Elasticsearch index mapping created for index '{es_index}'")
    else:
        print(f"Failed to create Elasticsearch index mapping. Status code: {response.status_code}")
        print(response.text)


if __name__ == "__main__":
    # 获取MySQL表字段信息
    table_fields = fetch_mysql_table_fields(mysql_config)

    # 生成Elasticsearch Mapping
    es_mapping = generate_es_mapping(table_fields)

    # 打印Elasticsearch Mapping到控制台
    print_es_mapping(es_mapping)

    # 创建Elasticsearch Index Mapping
    create_es_index_mapping(es_host, es_port, es_index, es_mapping)
相关推荐
叫我龙翔11 分钟前
【MySQL】从零开始了解数据库开发 --- 如何理解事务隔离性
数据库·mysql·数据库开发
程序员爱钓鱼1 小时前
Python编程实战 · 基础入门篇 | 类型转换与输入输出
后端·python
程序员爱钓鱼1 小时前
Python编程实战 · 基础入门篇 | 运算符详解
后端·python·编程语言
潜心编码1 小时前
基于Flask的志愿者管理系统
后端·python·flask
极限实验室2 小时前
搜索百科(5):Easysearch — 自主可控的国产分布式搜索引擎
elasticsearch·搜索引擎
开心-开心急了2 小时前
Flask入门教程——李辉 第四章 静态文件 关键知识梳理 更新1次
后端·python·flask
应用市场9 小时前
构建自定义命令行工具 - 打造专属指令体
开发语言·windows·python
东方佑9 小时前
从字符串中提取重复子串的Python算法解析
windows·python·算法
Dfreedom.10 小时前
一文掌握Python四大核心数据结构:变量、结构体、类与枚举
开发语言·数据结构·python·变量·数据类型
一半烟火以谋生10 小时前
Python + Pytest + Allure 自动化测试报告教程
开发语言·python·pytest