使用duckdb加载mysql

安装duckdb

https://duckdb.org/docs/installation/index

加载mysql扩展

https://duckdb.org/docs/extensions/mysql.html
离线安装的话,可以等INSTALL mysql;超时后,根据它提示的URL到有网环境下载,再传到服务器挂载Nginx,修改/etc/hosts指向,再重新执行INSTALL。

Demo代码如下:

import duckdb

DB_HOST = "localhost"
DB_USERNAME = "root"
DB_PASS = "123456"
DB_PORT = 3306
DB_NAME = "test_1"

PARAMETERS = f"host={DB_HOST} user={DB_USERNAME} passwd={DB_PASS} port={DB_PORT} database={DB_NAME}"
ATTACH_QUERY = f"ATTACH '{PARAMETERS}' AS user (TYPE mysql);"
USE_QUERY = "USE user;"

with duckdb.connect() as con:
    con.install_extension("mysql")
    con.load_extension("mysql")
    con.sql(ATTACH_QUERY)
    con.sql(USE_QUERY)
    con.sql("SHOW TABLES").show()
    res = con.sql("select * from user;")
    res.show()
    data: list[tuple] = res.fetchall()
    print(f"fetchall: {data!r}")

封装成上下文管理器

from contextlib import contextmanager
from typing import Generator

import asynctor
import duckdb
from duckdb import DuckDBPyConnection


@contextmanager
def duck_client(
    database: str, host="localhost", user="root", passwd="123456", port=3306
) -> Generator[DuckDBPyConnection, None, None]:
    """使用duckdb连接mysql

    Usage::
        >>> with duck_client() as conn:
        ...     conn.sql('show tables').show()
    """

    PARAMETERS = f"host={host} user={user} passwd={passwd} {port=} database={database}"
    ATTACH_QUERY = f"ATTACH '{PARAMETERS}' AS user (TYPE mysql);"
    USE_QUERY = "USE user;"
    with duckdb.connect() as con:
        con.install_extension("mysql")
        con.load_extension("mysql")
        con.sql(ATTACH_QUERY)
        con.sql(USE_QUERY)
        yield con


@asynctor.timeit
def main() -> None:
    with duck_client("test_1") as conn:
        conn.sql("show tables").show()


if __name__ == "__main__":
    main()
posted @ 2024-08-19 12:17  waketzheng  阅读(336)  评论(0编辑  收藏  举报