mdbq 1.2.3__tar.gz → 1.2.4__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-1.2.3 → mdbq-1.2.4}/PKG-INFO +1 -1
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/aggregation/aggregation.py +4 -3
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/aggregation/mysql_types.py +6 -2
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/dataframe/converter.py +5 -2
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/mysql/mysql.py +46 -12
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq.egg-info/PKG-INFO +1 -1
- {mdbq-1.2.3 → mdbq-1.2.4}/setup.py +1 -1
- {mdbq-1.2.3 → mdbq-1.2.4}/README.txt +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/__init__.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/__version__.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/aggregation/__init__.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/aggregation/df_types.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/aggregation/optimize_data.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/aggregation/query_data.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/bdup/__init__.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/bdup/bdup.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/clean/__init__.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/clean/data_clean.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/company/__init__.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/company/copysh.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/config/__init__.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/config/get_myconf.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/config/products.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/config/set_support.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/config/update_conf.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/dataframe/__init__.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/log/__init__.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/log/mylogger.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/mongo/__init__.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/mongo/mongo.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/mysql/__init__.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/mysql/data_types_/345/215/263/345/260/206/345/210/240/351/231/244.py" +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/mysql/s_query.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/mysql/year_month_day.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/other/__init__.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/other/porxy.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/other/pov_city.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/other/ua_sj.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/pbix/__init__.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/pbix/pbix_refresh.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/pbix/refresh_all.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq/spider/__init__.py +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq.egg-info/SOURCES.txt +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq.egg-info/dependency_links.txt +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/mdbq.egg-info/top_level.txt +0 -0
- {mdbq-1.2.3 → mdbq-1.2.4}/setup.cfg +0 -0
@@ -930,7 +930,7 @@ def one_file_to_mysql(file, db_name, table_name, target_service, database):
|
|
930
930
|
filename = os.path.basename(file)
|
931
931
|
df = pd.read_csv(file, encoding='utf-8_sig', header=0, na_filter=False, float_precision='high')
|
932
932
|
m = mysql.MysqlUpload(username=username, password=password, host=host, port=port)
|
933
|
-
m.df_to_mysql(df=df, db_name=db_name, table_name=table_name, filename=filename)
|
933
|
+
m.df_to_mysql(df=df, db_name=db_name, table_name=table_name, filename=filename, df_sql=True)
|
934
934
|
|
935
935
|
|
936
936
|
def file_dir(one_file=True):
|
@@ -975,6 +975,7 @@ def file_dir(one_file=True):
|
|
975
975
|
path=os.path.join(path, sub_path),
|
976
976
|
db_name = db_name,
|
977
977
|
collection_name = table_name,
|
978
|
+
dbs={'mysql': True, 'mongodb': True},
|
978
979
|
)
|
979
980
|
data.update({'入库进度': 1}) # 更新进度为已上传
|
980
981
|
# 将进度信息写回文件
|
@@ -1000,9 +1001,9 @@ if __name__ == '__main__':
|
|
1000
1001
|
# print(username, password, host, port)
|
1001
1002
|
file_dir(one_file=False)
|
1002
1003
|
# one_file_to_mysql(
|
1003
|
-
# file='',
|
1004
|
+
# file='/Users/xigua/数据中心/原始文件2/京东报表/商品信息导出/spu/京东商品信息_批量SPU导出-批量任务_2024-08-10.csv',
|
1004
1005
|
# db_name='京东数据2',
|
1005
|
-
# table_name='
|
1006
|
+
# table_name='京东spu商品信息',
|
1006
1007
|
# target_service='home_lx',
|
1007
1008
|
# database='mysql'
|
1008
1009
|
# )
|
@@ -206,6 +206,7 @@ def mysql_all_dtypes(db_name=None, table_name=None, path=None):
|
|
206
206
|
time.sleep(0.5)
|
207
207
|
|
208
208
|
d = DataTypes()
|
209
|
+
d.json_file = os.path.join(path, 'mysql_types.json') # # json 保存位置
|
209
210
|
for result in results:
|
210
211
|
for db_n, table_n in result.items():
|
211
212
|
# print(db_n, table_n, db_name, table_name)
|
@@ -230,7 +231,7 @@ def mysql_all_dtypes(db_name=None, table_name=None, path=None):
|
|
230
231
|
cl='mysql',
|
231
232
|
db_name=db_n,
|
232
233
|
table_name=table_n,
|
233
|
-
is_file_dtype=True
|
234
|
+
is_file_dtype=True # True表示旧文件有限
|
234
235
|
)
|
235
236
|
else:
|
236
237
|
print(f'数据库回传数据(name_type)为空')
|
@@ -239,4 +240,7 @@ def mysql_all_dtypes(db_name=None, table_name=None, path=None):
|
|
239
240
|
|
240
241
|
|
241
242
|
if __name__ == '__main__':
|
242
|
-
|
243
|
+
# 更新 mysql 中所有数据库的 dtypes 信息到本地 json
|
244
|
+
mysql_all_dtypes(
|
245
|
+
path='/Users/xigua/Downloads',
|
246
|
+
)
|
@@ -43,11 +43,14 @@ class DataFrameConverter(object):
|
|
43
43
|
df[col] = df[col].apply(lambda x: float(float((str(x).rstrip("%"))) / 100) if str(x).endswith('%') and '~' not in str(x) else x)
|
44
44
|
# 尝试转换合适的数据类型
|
45
45
|
if df[col].dtype == 'object':
|
46
|
+
# "_"符号会被错误识别
|
46
47
|
try:
|
47
|
-
df[col] = df[col].apply(lambda x: int(x) if '_' not in str(x) else x)
|
48
|
+
df[col] = df[col].apply(lambda x: int(x) if '_' not in str(x) and '.' not in str(x) else x) # 不含小数点尝试转整数
|
48
49
|
except:
|
50
|
+
pass
|
51
|
+
if df[col].dtype == 'object':
|
49
52
|
try:
|
50
|
-
df[col] = df[col].apply(lambda x: float(x) if '_' not in str(x) else x)
|
53
|
+
df[col] = df[col].apply(lambda x: float(x) if '.' in str(x) and '_' not in str(x) else x)
|
51
54
|
except:
|
52
55
|
pass
|
53
56
|
if df[col].dtype == 'float' or df[col].dtype == 'float64': # 对于小数类型, 保留 6 位小数
|
@@ -9,7 +9,9 @@ import warnings
|
|
9
9
|
import pymysql
|
10
10
|
import numpy as np
|
11
11
|
import pandas as pd
|
12
|
+
import sqlalchemy.types
|
12
13
|
from more_itertools.more import iequals
|
14
|
+
from pandas.core.dtypes.common import INT64_DTYPE
|
13
15
|
from sqlalchemy import create_engine
|
14
16
|
import os
|
15
17
|
import calendar
|
@@ -20,19 +22,20 @@ from mdbq.aggregation import mysql_types
|
|
20
22
|
|
21
23
|
warnings.filterwarnings('ignore')
|
22
24
|
"""
|
23
|
-
|
25
|
+
建表流程:
|
24
26
|
尽可能手动建表,再上传数据
|
25
|
-
1.
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
1. 每个表手动上传一个文件建表
|
28
|
+
2. 全部建表完成,建议所有表的数据类型,有问题的在数据库修改
|
29
|
+
3. 清空所有数据表,仅保留列信息
|
30
|
+
4. 下载所有数据表的 dtypes 信息到 json 文件
|
31
|
+
5. 之后可以正常上传数据
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
建表规范:
|
34
|
+
1. 数据库和数据表名如果有字母,必须使用小写,大写在建库后会自动变小写,再次上传数据会找不到数据库(macos和linux都有这种情况)
|
35
|
+
2. 无论是数据库/表/列名还是值,尽量避免特殊字符或者表情符号,数据库/表/列名尽量都使用 `列名` 转义,避免错误
|
36
|
+
3. 小数必须使用 decimal, 禁止 float 和 double, 因为计算精度差异,后续需要聚合数据时会引发很多问题
|
37
|
+
4. 日期类型暂时全部用 DATETIME,使用 DATE 在后续可能会重复插入不能排重,因为 df 进来的数据, 日期是带时间的,而数据库中日期不含时间
|
38
|
+
5. 目前小数自动适配类型转换,对于文本或者大数全部用 mediumtext, 因为部分表涉及爬虫数据,进来的字符长度未知,暂时统一 mediumtext 避免入库失败
|
36
39
|
|
37
40
|
|
38
41
|
|
@@ -57,7 +60,7 @@ class MysqlUpload:
|
|
57
60
|
}
|
58
61
|
self.filename = None
|
59
62
|
|
60
|
-
def df_to_mysql(self, df, table_name, db_name='远程数据源', drop_dup=True, drop_duplicates=False, filename=None, count=None):
|
63
|
+
def df_to_mysql(self, df, table_name, db_name='远程数据源', df_sql=False, drop_dup=True, drop_duplicates=False, filename=None, count=None):
|
61
64
|
"""
|
62
65
|
将 df 写入数据库
|
63
66
|
db_name: 数据库名称
|
@@ -74,9 +77,23 @@ class MysqlUpload:
|
|
74
77
|
else:
|
75
78
|
print(f'{db_name}: {table_name} 传入的 df 不是有效的 dataframe 结构, {self.filename}')
|
76
79
|
return
|
80
|
+
|
77
81
|
cv = converter.DataFrameConverter()
|
78
82
|
df = cv.convert_df_cols(df=df) # 清理 dataframe 非法值
|
79
83
|
|
84
|
+
# if df_sql:
|
85
|
+
# now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S ")
|
86
|
+
# print(f'{now}正在更新 mysql ({self.host}:{self.port}) {db_name}/{table_name}, {count},{self.filename}')
|
87
|
+
# engine = create_engine(f"mysql+pymysql://{self.username}:{self.password}@{self.host}:{self.port}/{db_name}") # 创建数据库引擎
|
88
|
+
# df.to_sql(
|
89
|
+
# name=table_name,
|
90
|
+
# con=engine,
|
91
|
+
# if_exists='append',
|
92
|
+
# index=False,
|
93
|
+
# chunksize=1000,
|
94
|
+
# dtype={'京东价': 'INT'},
|
95
|
+
# )
|
96
|
+
# return
|
80
97
|
connection = pymysql.connect(**self.config) # 连接数据库
|
81
98
|
with connection.cursor() as cursor:
|
82
99
|
cursor.execute(f"SHOW DATABASES LIKE '{db_name}'") # 检查数据库是否存在
|
@@ -133,6 +150,21 @@ class MysqlUpload:
|
|
133
150
|
print(f'{self.filename}: {e}')
|
134
151
|
connection.commit() # 提交事务
|
135
152
|
|
153
|
+
if df_sql:
|
154
|
+
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S ")
|
155
|
+
print(f'{now}正在更新 mysql ({self.host}:{self.port}) {db_name}/{table_name}, {count},{self.filename}')
|
156
|
+
engine = create_engine(
|
157
|
+
f"mysql+pymysql://{self.username}:{self.password}@{self.host}:{self.port}/{db_name}") # 创建数据库引擎
|
158
|
+
df.to_sql(
|
159
|
+
name=table_name,
|
160
|
+
con=engine,
|
161
|
+
if_exists='append',
|
162
|
+
index=False,
|
163
|
+
chunksize=1000
|
164
|
+
)
|
165
|
+
connection.close()
|
166
|
+
return
|
167
|
+
|
136
168
|
# print(cl, db_n, tb_n)
|
137
169
|
# 返回这些结果的目的是等添加完列再写 json 文件才能读到 types 信息
|
138
170
|
if cl and db_n and tb_n:
|
@@ -154,6 +186,7 @@ class MysqlUpload:
|
|
154
186
|
# 5. 更新插入数据
|
155
187
|
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S ")
|
156
188
|
print(f'{now}正在更新 mysql ({self.host}:{self.port}) {db_name}/{table_name}, {count},{self.filename}')
|
189
|
+
|
157
190
|
datas = df.to_dict(orient='records')
|
158
191
|
for data in datas:
|
159
192
|
try:
|
@@ -185,6 +218,7 @@ class MysqlUpload:
|
|
185
218
|
print(f'mysql -> df_to_mysql 报错: {e}, {self.filename}')
|
186
219
|
# breakpoint()
|
187
220
|
connection.commit() # 提交事务
|
221
|
+
connection.close()
|
188
222
|
|
189
223
|
def convert_dtypes(self, df, db_name, table_name):
|
190
224
|
"""
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{mdbq-1.2.3 → mdbq-1.2.4}/mdbq/mysql/data_types_/345/215/263/345/260/206/345/210/240/351/231/244.py"
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|