mdbq 0.4.5__tar.gz → 1.0.0__tar.gz
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.
- {mdbq-0.4.5 → mdbq-1.0.0}/PKG-INFO +1 -1
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/aggregation/aggregation.py +27 -140
- mdbq-1.0.0/mdbq/aggregation/df_types.py +180 -0
- mdbq-1.0.0/mdbq/aggregation/mysql_types.py +231 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/aggregation/query_data.py +1 -1
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/dataframe/converter.py +45 -0
- mdbq-0.4.5/mdbq/mysql/data_types.py → mdbq-1.0.0/mdbq/mysql/data_types_/345/215/263/345/260/206/345/210/240/351/231/244.py +19 -8
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/mysql/mysql.py +148 -191
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq.egg-info/PKG-INFO +1 -1
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq.egg-info/SOURCES.txt +3 -1
- {mdbq-0.4.5 → mdbq-1.0.0}/setup.py +1 -1
- {mdbq-0.4.5 → mdbq-1.0.0}/README.txt +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/__init__.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/__version__.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/aggregation/__init__.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/aggregation/optimize_data.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/bdup/__init__.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/bdup/bdup.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/clean/__init__.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/clean/data_clean.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/company/__init__.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/company/copysh.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/config/__init__.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/config/get_myconf.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/config/products.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/config/set_support.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/config/update_conf.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/dataframe/__init__.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/log/__init__.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/log/mylogger.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/mongo/__init__.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/mongo/mongo.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/mysql/__init__.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/mysql/s_query.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/mysql/year_month_day.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/other/__init__.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/other/porxy.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/other/pov_city.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/other/ua_sj.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/pbix/__init__.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/pbix/pbix_refresh.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/pbix/refresh_all.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq/spider/__init__.py +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq.egg-info/dependency_links.txt +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/mdbq.egg-info/top_level.txt +0 -0
- {mdbq-0.4.5 → mdbq-1.0.0}/setup.cfg +0 -0
@@ -11,6 +11,7 @@ import platform
|
|
11
11
|
import json
|
12
12
|
from mdbq.mongo import mongo
|
13
13
|
from mdbq.mysql import mysql
|
14
|
+
from mdbq.aggregation import df_types
|
14
15
|
from mdbq.config import get_myconf
|
15
16
|
from mdbq.config import set_support
|
16
17
|
from mdbq.dataframe import converter
|
@@ -25,109 +26,15 @@ warnings.filterwarnings('ignore')
|
|
25
26
|
1. DatabaseUpdate: 程序用于对爬虫下载的原始数据进行清洗并入库;
|
26
27
|
数据清洗主要包括对字段名的非法字符处理,对 df 中的非法值进行预处理;
|
27
28
|
数据入库时会较检并更新本地 json 文件的 dtypes 信息;
|
28
|
-
若 json 缺失 dtypes 信息, 可用
|
29
|
+
若 json 缺失 dtypes 信息, 可用 update_df_types_to_json 先更新, 或者手动修改添加本地 json 信息;
|
29
30
|
2. DataTypes: 类用于将某个csv文件的 dtypes 信息存入本地 json 文件, 会调用 converter 对 df 预处理;
|
30
31
|
作用于完善某个数据库 dtypes 信息,可以使用本函数更新;
|
31
|
-
3.
|
32
|
+
3. update_df_types_to_json: 函数将一个 csv 文件的 dtypes 信息更新至本地 json 文件;
|
32
33
|
4. upload: 函数将一个文件夹上传至数据库;
|
33
|
-
如果本地 json 中确实这个数据库的 dtypes 信息, 请用
|
34
|
+
如果本地 json 中确实这个数据库的 dtypes 信息, 请用 update_df_types_to_json 更新 json 文件再执行数据上传;
|
34
35
|
"""
|
35
36
|
|
36
37
|
|
37
|
-
class DataTypes:
|
38
|
-
"""
|
39
|
-
将某表的列信息添加到 json 示例:
|
40
|
-
file = '/Users/xigua/Downloads/天猫直通车旧报表(未排重版本).csv'
|
41
|
-
df = pd.read_csv(file, encoding='utf-8_sig', header=0, na_filter=False)
|
42
|
-
d = DataTypes()
|
43
|
-
d.read_dtypes(
|
44
|
-
df=df,
|
45
|
-
db_name='天猫数据2',
|
46
|
-
collection_name='旧版报表',
|
47
|
-
is_file_dtype=False, # 关闭文件优先
|
48
|
-
)
|
49
|
-
d.dtypes_to_file()
|
50
|
-
"""
|
51
|
-
def __init__(self):
|
52
|
-
self.path = set_support.SetSupport(dirname='support').dirname
|
53
|
-
if not os.path.exists(self.path):
|
54
|
-
os.mkdir(self.path)
|
55
|
-
self.json_file = os.path.join(self.path, 'data_types.json')
|
56
|
-
# self.datas = json.loads('{}') # 等待写入 json 文件的 dtypes 数据
|
57
|
-
self.datas = {'json统计': {'数据库量': 0, '集合数量': 0, '字段量': 0}}
|
58
|
-
self.json_before()
|
59
|
-
|
60
|
-
def json_before(self):
|
61
|
-
""" 本地 json 文件的 dtypes 信息, 初始化更新给 self.datas """
|
62
|
-
if os.path.isfile(self.json_file):
|
63
|
-
with open(self.json_file, 'r', encoding='utf-8_sig') as json_file:
|
64
|
-
json_ = json.load(json_file)
|
65
|
-
self.datas.update(json_)
|
66
|
-
|
67
|
-
def load_dtypes(self, db_name, collection_name, ):
|
68
|
-
return self.datas[db_name][collection_name]
|
69
|
-
|
70
|
-
|
71
|
-
def read_dtypes(self, db_name, collection_name, df=pd.DataFrame(), is_file_dtype=True):
|
72
|
-
"""
|
73
|
-
读取 df 的 dtypes, 并更新本地 json 文件
|
74
|
-
期间会 清理不合规的列名, 并对数据类型进行转换(尝试将 object 类型转为 int 或 float)
|
75
|
-
返回: df 的 dtypes, 后续使用示例: df = df.astype(dtypes, errors='ignore')
|
76
|
-
is_file_dtype=True: 默认情况下以旧 json 优先, 即允许手动指定 json 文件里面的数据类型
|
77
|
-
"""
|
78
|
-
if len(df) == 0:
|
79
|
-
return
|
80
|
-
cv = converter.DataFrameConverter()
|
81
|
-
df = cv.convert_df_cols(df=df) # 清理 dataframe 列名的不合规字符
|
82
|
-
dtypes = df.dtypes.apply(str).to_dict()
|
83
|
-
dtypes = {db_name: {collection_name: dtypes}}
|
84
|
-
|
85
|
-
if not self.datas: # 如果不存在本地 json 文件, 直接返回即可
|
86
|
-
self.datas.update(dtypes)
|
87
|
-
return self.datas[db_name][collection_name]
|
88
|
-
else: # 存在则读取,并更新 df 的 dtypes
|
89
|
-
if db_name in list(self.datas.keys()): # ['京东数据2', '天猫数据2', '生意参谋数据2', '生意经2']
|
90
|
-
if collection_name in list(self.datas[db_name].keys()):
|
91
|
-
if is_file_dtype: # 旧数据优先
|
92
|
-
# # 用 dtypes 更新, 允许手动指定 json 文件里面的数据类型
|
93
|
-
dtypes[db_name][collection_name].update(self.datas[db_name][collection_name])
|
94
|
-
# 将 dtypes 更新进去,使 self.datas 包含新旧信息
|
95
|
-
self.datas[db_name][collection_name].update(dtypes[db_name][collection_name])
|
96
|
-
else: # 新数据优先
|
97
|
-
self.datas[db_name][collection_name].update(dtypes[db_name][collection_name])
|
98
|
-
else:
|
99
|
-
if is_file_dtype: # 旧数据优先
|
100
|
-
dtypes[db_name].update(self.datas[db_name])
|
101
|
-
self.datas[db_name].update(dtypes[db_name])
|
102
|
-
else:
|
103
|
-
self.datas[db_name].update(dtypes[db_name])
|
104
|
-
else:
|
105
|
-
# dtypes.update(self.datas) # 可以注释掉, 因为旧数据 self.datas 是空的
|
106
|
-
self.datas.update(dtypes)
|
107
|
-
dbs = 0
|
108
|
-
collections = 0
|
109
|
-
cols = 0
|
110
|
-
# self.datas.pop('json统计')
|
111
|
-
for k, v in self.datas.items():
|
112
|
-
if k == 'json统计':
|
113
|
-
continue
|
114
|
-
dbs += 1
|
115
|
-
for d, j in v.items():
|
116
|
-
collections += 1
|
117
|
-
for t, p in j.items():
|
118
|
-
cols += 1
|
119
|
-
tips = {'json统计': {'数据库量': dbs, '集合数量': collections, '字段量': cols}}
|
120
|
-
self.datas.update(tips)
|
121
|
-
return self.datas[db_name][collection_name] # 返回 df 的 dtypes
|
122
|
-
|
123
|
-
def dtypes_to_file(self):
|
124
|
-
""" 保存为本地 json 文件 """
|
125
|
-
# print(self.datas)
|
126
|
-
with open(self.json_file, 'w', encoding='utf-8_sig') as f:
|
127
|
-
json.dump(self.datas, f, ensure_ascii=False, sort_keys=True, indent=4)
|
128
|
-
time.sleep(1)
|
129
|
-
|
130
|
-
|
131
38
|
class DatabaseUpdate:
|
132
39
|
def __init__(self, path):
|
133
40
|
self.path = path # 数据所在目录, 即: 下载文件夹
|
@@ -142,7 +49,6 @@ class DatabaseUpdate:
|
|
142
49
|
print(f'1.1.0 初始化时传入了不存在的目录: {self.path}')
|
143
50
|
return
|
144
51
|
|
145
|
-
json_data = DataTypes() # json 文件, 包含数据的 dtypes 信息
|
146
52
|
for root, dirs, files in os.walk(self.path, topdown=False):
|
147
53
|
for name in files:
|
148
54
|
if '~$' in name or '.DS' in name or '.localized' in name or '.ini' in name or '$RECYCLE.BIN' in name or 'Icon' in name:
|
@@ -680,13 +586,6 @@ class DatabaseUpdate:
|
|
680
586
|
except Exception as e:
|
681
587
|
print(f'{name}, {e}')
|
682
588
|
if len(df) > 0:
|
683
|
-
# 创建包含 dtypes 信息的 json 文件
|
684
|
-
json_data.read_dtypes(
|
685
|
-
df=df,
|
686
|
-
db_name=db_name,
|
687
|
-
collection_name=collection_name,
|
688
|
-
is_file_dtype=True, # 默认本地文件优先: True
|
689
|
-
)
|
690
589
|
# 将数据传入 self.datas 等待更新进数据库
|
691
590
|
self.datas.append(
|
692
591
|
{
|
@@ -695,10 +594,8 @@ class DatabaseUpdate:
|
|
695
594
|
'数据主体': df,
|
696
595
|
}
|
697
596
|
)
|
698
|
-
json_data.dtypes_to_file() # 写入 json 文件, 包含数据的 dtypes 信息
|
699
597
|
|
700
598
|
# 品销宝一个表格里面包含多个 sheet, 最好是单独处理
|
701
|
-
json_data = DataTypes() # json 文件, 包含数据的 dtypes 信息
|
702
599
|
for root, dirs, files in os.walk(self.path, topdown=False):
|
703
600
|
for name in files:
|
704
601
|
if '~$' in name or '.DS' in name or '.localized' in name or '.jpg' in name or '.png' in name:
|
@@ -720,12 +617,6 @@ class DatabaseUpdate:
|
|
720
617
|
df.insert(loc=1, column='报表类型', value=sheet4)
|
721
618
|
db_name = '天猫数据2'
|
722
619
|
collection_name = f'推广数据_品销宝_{sheet4}'
|
723
|
-
json_data.read_dtypes(
|
724
|
-
df=df,
|
725
|
-
db_name=db_name,
|
726
|
-
collection_name=collection_name,
|
727
|
-
is_file_dtype=False,
|
728
|
-
)
|
729
620
|
self.datas.append(
|
730
621
|
{
|
731
622
|
'数据库名': db_name,
|
@@ -735,7 +626,6 @@ class DatabaseUpdate:
|
|
735
626
|
)
|
736
627
|
if is_move:
|
737
628
|
os.remove(os.path.join(root, name))
|
738
|
-
json_data.dtypes_to_file() # 写入 json 文件, 包含数据的 dtypes 信息
|
739
629
|
|
740
630
|
df = self.date_table() # 创建一个日期表
|
741
631
|
self.datas.append(
|
@@ -750,6 +640,7 @@ class DatabaseUpdate:
|
|
750
640
|
"""
|
751
641
|
将清洗后的 df 上传数据库
|
752
642
|
"""
|
643
|
+
df_to_json = dtypes.DataTypes() # json 文件, 包含数据的 dtypes 信息
|
753
644
|
for service_database in service_databases:
|
754
645
|
for service_name, database in service_database.items():
|
755
646
|
# print(service_name, database)
|
@@ -766,7 +657,13 @@ class DatabaseUpdate:
|
|
766
657
|
drop_duplicates=False,
|
767
658
|
)
|
768
659
|
for data in self.datas:
|
769
|
-
|
660
|
+
db_name, collection_name, df = data['数据库名'], data['集合名称'], data['数据主体']
|
661
|
+
df_to_json.get_df_types(
|
662
|
+
df=df,
|
663
|
+
db_name=db_name,
|
664
|
+
collection_name=collection_name,
|
665
|
+
is_file_dtype=True, # 默认本地文件优先: True
|
666
|
+
)
|
770
667
|
d.df_to_mongo(df=df, db_name=db_name, collection_name=collection_name)
|
771
668
|
|
772
669
|
elif database == 'mysql':
|
@@ -782,7 +679,14 @@ class DatabaseUpdate:
|
|
782
679
|
)
|
783
680
|
for data in self.datas:
|
784
681
|
df, db_name, collection_name = data['数据主体'], data['数据库名'], data['集合名称']
|
682
|
+
df_to_json.get_df_types(
|
683
|
+
df=df,
|
684
|
+
db_name=db_name,
|
685
|
+
collection_name=collection_name,
|
686
|
+
is_file_dtype=True, # 默认本地文件优先: True
|
687
|
+
)
|
785
688
|
m.df_to_mysql(df=df, db_name=db_name, tabel_name=collection_name)
|
689
|
+
df_to_json.as_json_file() # 写入 json 文件, 包含数据的 dtypes 信息
|
786
690
|
|
787
691
|
def new_unzip(self, path=None, is_move=None):
|
788
692
|
"""
|
@@ -929,26 +833,9 @@ class DatabaseUpdate:
|
|
929
833
|
df.sort_values('日期', ascending=False, ignore_index=True, inplace=True)
|
930
834
|
return df
|
931
835
|
|
932
|
-
def update_dtypte():
|
933
|
-
""" 更新一个文件的 dtype 信息到 json 文件 """
|
934
|
-
file = '/Users/xigua/数据中心/原始文件2/月数据/流量来源/【生意参谋平台】无线店铺流量来源-2023-04-01_2023-04-30.csv'
|
935
|
-
df = pd.read_csv(file, encoding='utf-8_sig', header=0, na_filter=False)
|
936
|
-
d = DataTypes()
|
937
|
-
d.read_dtypes(
|
938
|
-
df=df,
|
939
|
-
db_name='生意参谋数据2',
|
940
|
-
collection_name='店铺来源_月数据',
|
941
|
-
is_file_dtype=True, # 日常需开启文件优先, 正常不要让新文件修改 json 已有的类型
|
942
|
-
)
|
943
|
-
d.dtypes_to_file()
|
944
|
-
|
945
836
|
|
946
|
-
def upload():
|
837
|
+
def upload(path, db_name, collection_name):
|
947
838
|
""" 上传一个文件夹到数据库 """
|
948
|
-
path = '/Users/xigua/数据中心/原始文件2/生意经/店铺指标'
|
949
|
-
db_name = '生意经2'
|
950
|
-
collection_name = '店铺指标'
|
951
|
-
|
952
839
|
username, password, host, port = get_myconf.select_config_values(
|
953
840
|
target_service='home_lx',
|
954
841
|
database='mongodb',
|
@@ -981,8 +868,8 @@ def upload():
|
|
981
868
|
port=port,
|
982
869
|
)
|
983
870
|
|
984
|
-
|
985
|
-
dtypes =
|
871
|
+
df_to_json = df_types.DataTypes()
|
872
|
+
dtypes = df_to_json.load_dtypes(
|
986
873
|
db_name=db_name,
|
987
874
|
collection_name=collection_name,
|
988
875
|
)
|
@@ -1007,8 +894,6 @@ def upload():
|
|
1007
894
|
intersection_keys = dtypes.keys() & old_dt.keys() # 获取两个字典键的交集
|
1008
895
|
dtypes = {k: dtypes[k] for k in intersection_keys} # 使用交集的键创建新字典
|
1009
896
|
df = df.astype(dtypes)
|
1010
|
-
# print(intersection_dict)
|
1011
|
-
# print(df)
|
1012
897
|
|
1013
898
|
d.df_to_mongo(df=df, db_name=db_name, collection_name=collection_name)
|
1014
899
|
m.df_to_mysql(df=df, db_name=db_name, tabel_name=collection_name)
|
@@ -1034,6 +919,8 @@ def main():
|
|
1034
919
|
if __name__ == '__main__':
|
1035
920
|
# username, password, host, port = get_myconf.select_config_values(target_service='nas', database='mysql')
|
1036
921
|
# print(username, password, host, port)
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
922
|
+
upload(
|
923
|
+
path='/Users/xigua/数据中心/原始文件2/生意经/地域分布',
|
924
|
+
db_name = '生意经2',
|
925
|
+
collection_name = '省份城市分析',
|
926
|
+
)
|
@@ -0,0 +1,180 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
import warnings
|
3
|
+
import pandas as pd
|
4
|
+
import numpy as np
|
5
|
+
import chardet
|
6
|
+
import zipfile
|
7
|
+
|
8
|
+
from numpy import dtype
|
9
|
+
from pandas.tseries.holiday import next_monday
|
10
|
+
from pyzipper import PyZipFile
|
11
|
+
import os
|
12
|
+
import platform
|
13
|
+
import json
|
14
|
+
import pymysql
|
15
|
+
from mdbq.mongo import mongo
|
16
|
+
from mdbq.mysql import mysql
|
17
|
+
from mdbq.mysql import s_query
|
18
|
+
from mdbq.config import get_myconf
|
19
|
+
from mdbq.config import set_support
|
20
|
+
from mdbq.dataframe import converter
|
21
|
+
import datetime
|
22
|
+
import time
|
23
|
+
import re
|
24
|
+
import shutil
|
25
|
+
import getpass
|
26
|
+
|
27
|
+
from sqlalchemy.dialects.postgresql.pg_catalog import pg_get_serial_sequence
|
28
|
+
|
29
|
+
warnings.filterwarnings('ignore')
|
30
|
+
"""
|
31
|
+
1. 记录 dataframe 或者数据库的列信息(dtypes)
|
32
|
+
2. 更新 mysql 中所有数据库的 dtypes 信息到本地 json
|
33
|
+
"""
|
34
|
+
|
35
|
+
|
36
|
+
class DataTypes:
|
37
|
+
"""
|
38
|
+
数据简介: 记录 dataframe 或者数据库的列信息(dtypes),可以记录其信息或者加载相关信息用于入库使用,
|
39
|
+
第一字段为分类(如 dataframe/mysql),第二字段为数据库名,第三字段为集合名,第四段列名及其数据类型
|
40
|
+
"""
|
41
|
+
def __init__(self):
|
42
|
+
self.datas = {
|
43
|
+
"json统计":
|
44
|
+
{
|
45
|
+
"字段量": 0,
|
46
|
+
"数据库量": 0,
|
47
|
+
"集合数量": 0
|
48
|
+
}
|
49
|
+
}
|
50
|
+
self.path = set_support.SetSupport(dirname='support').dirname
|
51
|
+
self.json_file = os.path.join(self.path, 'df_types.json')
|
52
|
+
if not os.path.isdir(self.path):
|
53
|
+
os.makedirs(self.path)
|
54
|
+
if not os.path.isfile(self.json_file):
|
55
|
+
with open(self.json_file, 'w', encoding='utf-8_sig') as f:
|
56
|
+
json.dump(self.datas, f, ensure_ascii=False, sort_keys=True, indent=4)
|
57
|
+
self.json_before()
|
58
|
+
|
59
|
+
def json_before(self):
|
60
|
+
""" 本地 json 文件的 dtypes 信息, 初始化更新给 self.datas """
|
61
|
+
with open(self.json_file, 'r', encoding='utf-8_sig') as f:
|
62
|
+
json_ = json.load(f)
|
63
|
+
self.datas.update(json_)
|
64
|
+
|
65
|
+
def get_df_types(self, db_name, collection_name, df=pd.DataFrame(), is_file_dtype=True):
|
66
|
+
"""
|
67
|
+
读取 df 的 dtypes, 并更新本地 json 文件
|
68
|
+
期间会 清理不合规的列名, 并对数据类型进行转换(尝试将 object 类型转为 int 或 float)
|
69
|
+
返回: df 的 dtypes, 后续使用示例: df = df.astype(dtypes, errors='ignore')
|
70
|
+
is_file_dtype=True: 默认情况下以旧 json 优先, 即允许手动指定 json 文件里面的数据类型
|
71
|
+
"""
|
72
|
+
if len(df) == 0:
|
73
|
+
return
|
74
|
+
cv = converter.DataFrameConverter()
|
75
|
+
df = cv.convert_df_cols(df=df) # 清理 dataframe 非法值
|
76
|
+
dtypes = df.dtypes.apply(str).to_dict()
|
77
|
+
dtypes = {db_name: {collection_name: dtypes}}
|
78
|
+
|
79
|
+
if not self.datas: # 如果不存在本地 json 文件, 直接返回即可
|
80
|
+
self.datas.update(dtypes)
|
81
|
+
return self.datas[db_name][collection_name]
|
82
|
+
else: # 存在则读取,并更新 df 的 dtypes
|
83
|
+
if db_name in list(self.datas.keys()): # ['京东数据2', '天猫数据2', '生意参谋数据2', '生意经2']
|
84
|
+
if collection_name in list(self.datas[db_name].keys()):
|
85
|
+
if is_file_dtype: # 旧数据优先
|
86
|
+
# # 用 dtypes 更新, 允许手动指定 json 文件里面的数据类型
|
87
|
+
dtypes[db_name][collection_name].update(self.datas[db_name][collection_name])
|
88
|
+
# 将 dtypes 更新进去,使 self.datas 包含新旧信息
|
89
|
+
self.datas[db_name][collection_name].update(dtypes[db_name][collection_name])
|
90
|
+
else: # 新数据优先
|
91
|
+
self.datas[db_name][collection_name].update(dtypes[db_name][collection_name])
|
92
|
+
else:
|
93
|
+
if is_file_dtype: # 旧数据优先
|
94
|
+
dtypes[db_name].update(self.datas[db_name])
|
95
|
+
self.datas[db_name].update(dtypes[db_name])
|
96
|
+
else:
|
97
|
+
self.datas[db_name].update(dtypes[db_name])
|
98
|
+
else:
|
99
|
+
# dtypes.update(self.datas) # 可以注释掉, 因为旧数据 self.datas 是空的
|
100
|
+
self.datas.update(dtypes)
|
101
|
+
dbs = 0
|
102
|
+
collections = 0
|
103
|
+
cols = 0
|
104
|
+
# self.datas.pop('json统计')
|
105
|
+
for k, v in self.datas.items():
|
106
|
+
if k == 'json统计':
|
107
|
+
continue
|
108
|
+
dbs += 1
|
109
|
+
for d, j in v.items():
|
110
|
+
collections += 1
|
111
|
+
for t, p in j.items():
|
112
|
+
cols += 1
|
113
|
+
tips = {'json统计': {'数据库量': dbs, '集合数量': collections, '字段量': cols}}
|
114
|
+
self.datas.update(tips)
|
115
|
+
return self.datas[db_name][collection_name] # 返回 df 的 dtypes
|
116
|
+
|
117
|
+
def as_json_file(self):
|
118
|
+
""" 保存为本地 json 文件 """
|
119
|
+
with open(self.json_file, 'w', encoding='utf-8_sig') as f:
|
120
|
+
json.dump(
|
121
|
+
self.datas,
|
122
|
+
f,
|
123
|
+
ensure_ascii=False, # 默认True,非ASCII字符将被转义。如为False,则非ASCII字符会以\uXXXX输出
|
124
|
+
sort_keys=True, # 默认为False。如果为True,则字典的输出将按键排序。
|
125
|
+
indent=4,
|
126
|
+
)
|
127
|
+
time.sleep(1)
|
128
|
+
|
129
|
+
def df_dtypes_to_json(self, db_name, collection_name, path, df=pd.DataFrame(), is_file_dtype=True):
|
130
|
+
if len(df) == 0:
|
131
|
+
return
|
132
|
+
cv = converter.DataFrameConverter()
|
133
|
+
df = cv.convert_df_cols(df=df) # 清理 dataframe 列名的不合规字符
|
134
|
+
dtypes = df.dtypes.apply(str).to_dict()
|
135
|
+
dtypes = {'dataframe': {db_name: {collection_name: dtypes}}}
|
136
|
+
self.dtypes_to_json(dtypes=dtypes, cl='dataframe', db_name=db_name, collection_name=collection_name, path=path, is_file_dtype=is_file_dtype)
|
137
|
+
|
138
|
+
def load_dtypes(self, db_name, collection_name):
|
139
|
+
if db_name in list(self.datas.keys()):
|
140
|
+
if collection_name in list(self.datas[db_name].keys()):
|
141
|
+
return self.datas[db_name][collection_name]
|
142
|
+
else:
|
143
|
+
print(f'不存在的集合名信息: {collection_name}, 文件位置: {self.json_file}')
|
144
|
+
return {}
|
145
|
+
else:
|
146
|
+
print(f'不存在的数据库信息: {db_name}, 文件位置: {self.json_file}')
|
147
|
+
return {}
|
148
|
+
|
149
|
+
|
150
|
+
def update_df_types_to_json(file, db_name, collection_name, is_file_dtype=True):
|
151
|
+
""" 更新一个文件的 dtype 信息到 json 文件 """
|
152
|
+
df = pd.read_csv(file, encoding='utf-8_sig', header=0, na_filter=False)
|
153
|
+
df_to_json = DataTypes()
|
154
|
+
df_to_json.get_df_types(
|
155
|
+
df=df,
|
156
|
+
db_name=db_name,
|
157
|
+
collection_name=collection_name,
|
158
|
+
is_file_dtype=is_file_dtype, # 日常需开启文件优先, 正常不要让新文件修改 json 已有的类型
|
159
|
+
)
|
160
|
+
df_to_json.as_json_file()
|
161
|
+
print(f'json文件已存储: {df_to_json.json_file}')
|
162
|
+
|
163
|
+
|
164
|
+
def test_load_dtypes(db_name, collection_name):
|
165
|
+
d = DataTypes()
|
166
|
+
res = d.load_dtypes(db_name=db_name, collection_name=collection_name)
|
167
|
+
print(res)
|
168
|
+
|
169
|
+
|
170
|
+
if __name__ == '__main__':
|
171
|
+
file = '/Users/xigua/数据中心/pandas数据源/店铺日报.csv'
|
172
|
+
update_df_types_to_json(
|
173
|
+
file=file,
|
174
|
+
db_name='pandas数据源',
|
175
|
+
collection_name='店铺日报',
|
176
|
+
is_file_dtype=True,
|
177
|
+
)
|
178
|
+
# test_load_dtypes(db_name='pandas数据源', collection_name='店铺日报')
|
179
|
+
|
180
|
+
|