microframex 2026.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
microframe/__init__.py ADDED
@@ -0,0 +1,2 @@
1
+ from .dataframe import DataFrame
2
+ from .reader import load
@@ -0,0 +1,75 @@
1
+ class DataFrame:
2
+ def __init__(self, rows, columns=None):
3
+
4
+ rows = list(rows) # 🔥 强制统一
5
+ self.rows = []
6
+
7
+ if not rows:
8
+ return
9
+
10
+ # ========= dict 输入 =========
11
+ if isinstance(rows[0], dict):
12
+ self.rows = rows
13
+ return
14
+
15
+ # ========= row + columns =========
16
+ if not columns:
17
+ columns = list(rows[0])
18
+ rows = rows[1:]
19
+
20
+ self.rows = [
21
+ dict(zip(columns, row))
22
+ for row in rows
23
+ ]
24
+
25
+ def validate_keys(self, keys):
26
+ cols = set(self.columns)
27
+ keys = set(keys)
28
+
29
+ missing = keys - cols
30
+ if missing:
31
+ raise KeyError(f"字段 “{missing}” 不存在")
32
+
33
+ @property
34
+ def columns(self):
35
+ if not self.rows:
36
+ return []
37
+ return list(self.rows[0].keys())
38
+
39
+ def head(self, n=5):
40
+ return DataFrame(self.rows[:n])
41
+
42
+ def groupby(self, *keys):
43
+
44
+ # 👉 统一校验
45
+ self.validate_keys(keys)
46
+
47
+ groups = {}
48
+
49
+ for row in self.rows:
50
+
51
+ if len(keys) == 1:
52
+ k = row.get(keys[0])
53
+ else:
54
+ k = tuple(row.get(key) for key in keys)
55
+
56
+ groups.setdefault(k, []).append(row)
57
+
58
+ return {k: DataFrame(v) for k, v in groups.items()}
59
+
60
+ def __repr__(self):
61
+ n = min(5, len(self.rows))
62
+ preview = self.rows[:n]
63
+
64
+ col_count = len(self.columns)
65
+
66
+ lines = [f"DataFrame(rows={len(self.rows)}, cols={col_count})("]
67
+
68
+ for row in preview:
69
+ lines.append(f" {row}")
70
+
71
+ if len(self.rows) > 5:
72
+ lines.append(f" ...")
73
+
74
+ lines.append(")")
75
+ return "\n".join(lines)
microframe/reader.py ADDED
@@ -0,0 +1,66 @@
1
+ from datetime import datetime
2
+ from os.path import basename
3
+ from .dataframe import DataFrame
4
+ from openpyxl import load_workbook
5
+ from sqlalchemy import create_engine, text
6
+
7
+ def format_datetime_with_milliseconds():
8
+ """格式化时间为 2026-03-12 14:17:45.618 格式"""
9
+ dt = datetime.now()
10
+ # 获取日期时间部分(不含毫秒)
11
+ base_time = dt.strftime("%Y-%m-%d %H:%M:%S")
12
+ # 获取毫秒(微秒除以1000)
13
+ milliseconds = dt.microsecond // 1000
14
+ # 格式化毫秒为3位数,不足补零
15
+ ms_str = f"{milliseconds:03d}"
16
+ return f"{base_time}.{ms_str}"
17
+
18
+ def load(source, sheet_name=None, query=None):
19
+ """
20
+ 读取数据源并返回 DataFrame
21
+
22
+ Parameters
23
+ ----------
24
+ source : str
25
+ - Excel 文件路径(.xlsx)
26
+ - MySQL 连接字符串(mysql+pymysql://user:pwd@host/db)
27
+ sheet_name : str, optional
28
+ Excel sheet 名称(默认第一个 sheet)
29
+ query : str, optional
30
+ SQL 查询语句(仅数据库模式必填)
31
+
32
+ Returns
33
+ -------
34
+ DataFrame
35
+ microframe.DataFrame
36
+ """
37
+
38
+ # ========== 1. Excel ==========
39
+ if source.lower().endswith(".xlsx"):
40
+ wb = load_workbook(source, read_only=True, data_only=True)
41
+
42
+ ws = wb[sheet_name] if sheet_name else wb.active
43
+
44
+ sheet_name = sheet_name if sheet_name else ws.title
45
+
46
+ print(f'\033[32m{format_datetime_with_milliseconds()} \033[31m| \033[0mINFO \033[31m|\033[0m 读取excel文件名称:\033[35m“{basename(source)}”\033[0m,sheet名称:\033[35m“{sheet_name}”\033[0m')
47
+
48
+ data = list(ws.values)
49
+ return DataFrame(data)
50
+
51
+ # ========== 2. MySQL ==========
52
+ if source.startswith("mysql"):
53
+ if not query:
54
+ raise ValueError("数据库模式下必须提供 query")
55
+
56
+ engine = create_engine(source)
57
+
58
+ with engine.connect() as conn:
59
+ result = conn.execute(text(query))
60
+ rows = result.fetchall()
61
+ columns = result.keys()
62
+
63
+ return DataFrame(rows, columns = columns)
64
+
65
+ # ========== 3. 不支持的数据源 ==========
66
+ raise ValueError(f"不支持的数据源类型: {source}")
microframe/writer.py ADDED
@@ -0,0 +1,4 @@
1
+ # encoding:utf-8
2
+ # @File: writer.py
3
+ # @Time: 2026/6/3 14:04
4
+ # @Author: 唐旭东
@@ -0,0 +1,13 @@
1
+ Metadata-Version: 2.4
2
+ Name: microframex
3
+ Version: 2026.1
4
+ Summary: 一个轻量级数据框架
5
+ Author: 唐旭东
6
+ Requires-Python: >=3.7
7
+ Requires-Dist: openpyxl
8
+ Requires-Dist: sqlalchemy
9
+ Requires-Dist: colorama
10
+ Dynamic: author
11
+ Dynamic: requires-dist
12
+ Dynamic: requires-python
13
+ Dynamic: summary
@@ -0,0 +1,8 @@
1
+ microframe/__init__.py,sha256=Ua45u9Bldecvgn1UAn3lZqU8WnBSbJaZnhBIwf-L44Q,58
2
+ microframe/dataframe.py,sha256=4ol7xEblNuLA23fUlbDCM26mj4Zfm1Kuv77csbv1YiI,1803
3
+ microframe/reader.py,sha256=wILRh4_sRhcEML95PnvVubtkWgg_R0S_Wxr_qRBDx1Y,2233
4
+ microframe/writer.py,sha256=LEZ17lROpeQnPDy2XCt1Ikb0qK5MIdmdeOByi7b1q3Y,85
5
+ microframex-2026.1.dist-info/METADATA,sha256=B9C9Tr96SDb8RXE8Z1cXKh5d4XBGBQ7WXQig6oc6-h0,302
6
+ microframex-2026.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
7
+ microframex-2026.1.dist-info/top_level.txt,sha256=E8duo4Yd6zWtch3JG12QFtWszaSx7QvFTMs_qHQpyAY,11
8
+ microframex-2026.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ microframe