rda-python-common 2.0.0__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.
- rda_python_common/PgCMD.py +603 -0
- rda_python_common/PgDBI.py +2306 -0
- rda_python_common/PgFile.py +3118 -0
- rda_python_common/PgLOG.py +1689 -0
- rda_python_common/PgLock.py +640 -0
- rda_python_common/PgOPT.py +1740 -0
- rda_python_common/PgSIG.py +1164 -0
- rda_python_common/PgSplit.py +299 -0
- rda_python_common/PgUtil.py +1854 -0
- rda_python_common/__init__.py +0 -0
- rda_python_common/pg_cmd.py +493 -0
- rda_python_common/pg_dbi.py +1885 -0
- rda_python_common/pg_file.py +2462 -0
- rda_python_common/pg_lock.py +533 -0
- rda_python_common/pg_log.py +1352 -0
- rda_python_common/pg_opt.py +1447 -0
- rda_python_common/pg_pass.py +92 -0
- rda_python_common/pg_sig.py +879 -0
- rda_python_common/pg_split.py +260 -0
- rda_python_common/pg_util.py +1534 -0
- rda_python_common/pgpassword.py +92 -0
- rda_python_common-2.0.0.dist-info/METADATA +20 -0
- rda_python_common-2.0.0.dist-info/RECORD +27 -0
- rda_python_common-2.0.0.dist-info/WHEEL +5 -0
- rda_python_common-2.0.0.dist-info/entry_points.txt +3 -0
- rda_python_common-2.0.0.dist-info/licenses/LICENSE +21 -0
- rda_python_common-2.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
#
|
|
2
|
+
###############################################################################
|
|
3
|
+
#
|
|
4
|
+
# Title : pg_split.py -- PostgreSQL DataBase Interface foe table wfile
|
|
5
|
+
# Author : Zaihua Ji, zji@ucar.edu
|
|
6
|
+
# Date : 09/010/2024
|
|
7
|
+
# 2025-01-10 transferred to package rda_python_common from
|
|
8
|
+
# https://github.com/NCAR/rda-shared-libraries.git
|
|
9
|
+
# 2025-12-01 convert to class PgSplit
|
|
10
|
+
# Purpose : Python library module to handle query and manipulate table wfile
|
|
11
|
+
#
|
|
12
|
+
# Github : https://github.com/NCAR/rda-python-common.git
|
|
13
|
+
#
|
|
14
|
+
###############################################################################
|
|
15
|
+
|
|
16
|
+
import os
|
|
17
|
+
import re
|
|
18
|
+
from os import path as op
|
|
19
|
+
from .pg_dbi import PgDBI
|
|
20
|
+
from .pg_util import PgUtil
|
|
21
|
+
|
|
22
|
+
class PgSplit(PgDBI):
|
|
23
|
+
|
|
24
|
+
def __init__(self):
|
|
25
|
+
super().__init__() # initialize parent class
|
|
26
|
+
|
|
27
|
+
# compare wfile records between tables wfile and wfile_dNNNNNN,
|
|
28
|
+
# and return the records need to be added, modified and deleted
|
|
29
|
+
@staticmethod
|
|
30
|
+
def compare_wfile(wfrecs, dsrecs):
|
|
31
|
+
flds = dsrecs.keys()
|
|
32
|
+
flen = len(flds)
|
|
33
|
+
arecs = dict(zip(flds, [[]]*flen))
|
|
34
|
+
mrecs = {}
|
|
35
|
+
drecs = []
|
|
36
|
+
wfcnt = len(wfrecs['wid'])
|
|
37
|
+
dscnt = len(dsrecs['wid'])
|
|
38
|
+
pi = pj = -1
|
|
39
|
+
i = j = 0
|
|
40
|
+
while i < wfcnt and j < dscnt:
|
|
41
|
+
if i > pi:
|
|
42
|
+
wfrec = PgUtil.onerecord(wfrecs, i)
|
|
43
|
+
wwid = wfrec['wid']
|
|
44
|
+
pi = i
|
|
45
|
+
if j > pj:
|
|
46
|
+
dsrec = PgUtil.onerecord(dsrecs, j)
|
|
47
|
+
dwid = dsrec['wid']
|
|
48
|
+
pj = j
|
|
49
|
+
if wwid == dwid:
|
|
50
|
+
mrec = PgSplit.compare_one_record(flds, wfrec, dsrec)
|
|
51
|
+
if mrec: mrecs[wwid] = mrec
|
|
52
|
+
i += 1
|
|
53
|
+
j += 1
|
|
54
|
+
elif wwid > dwid:
|
|
55
|
+
drecs.append(dwid)
|
|
56
|
+
j += 1
|
|
57
|
+
else:
|
|
58
|
+
for fld in flds:
|
|
59
|
+
arecs[fld].append(wfrec[fld])
|
|
60
|
+
i += 1
|
|
61
|
+
if i < wfcnt:
|
|
62
|
+
for fld in flds:
|
|
63
|
+
arecs[fld].extend(wfrecs[fld][i:wfcnt])
|
|
64
|
+
elif j < dscnt:
|
|
65
|
+
drecs.extend(dsrecs['wid'][j:dscnt])
|
|
66
|
+
if len(arecs['wid']) == 0: arecs = {}
|
|
67
|
+
return (arecs, mrecs, drecs)
|
|
68
|
+
|
|
69
|
+
# Compare column values and return the new one; empty if the same
|
|
70
|
+
@staticmethod
|
|
71
|
+
def compare_one_record(flds, wfrec, dsrec):
|
|
72
|
+
mrec = {}
|
|
73
|
+
for fld in flds:
|
|
74
|
+
if wfrec[fld] != dsrec[fld]: mrec[fld] = wfrec[fld]
|
|
75
|
+
return mrec
|
|
76
|
+
|
|
77
|
+
# convert wfile records to wfile_dsid records
|
|
78
|
+
@staticmethod
|
|
79
|
+
def wfile2wdsid(wfrecs, wids = None):
|
|
80
|
+
dsrecs = {}
|
|
81
|
+
if wfrecs:
|
|
82
|
+
for fld in wfrecs:
|
|
83
|
+
if fld == 'dsid': continue
|
|
84
|
+
dsrecs[fld] = wfrecs[fld]
|
|
85
|
+
if wids: dsrecs['wid'] = wids
|
|
86
|
+
return dsrecs
|
|
87
|
+
|
|
88
|
+
# trim wfile records
|
|
89
|
+
@staticmethod
|
|
90
|
+
def trim_wfile_fields(wfrecs):
|
|
91
|
+
records = {}
|
|
92
|
+
if 'wfile' in wfrecs: records['wfile'] = wfrecs['wfile']
|
|
93
|
+
if 'dsid' in wfrecs: records['dsid'] = wfrecs['dsid']
|
|
94
|
+
return records
|
|
95
|
+
|
|
96
|
+
# check the condition string, and add dsid if needed
|
|
97
|
+
@staticmethod
|
|
98
|
+
def get_dsid_condition(dsid, condition):
|
|
99
|
+
if condition:
|
|
100
|
+
if re.search(r'(^|.| )(wid|dsid)\s*=', condition):
|
|
101
|
+
return condition
|
|
102
|
+
else:
|
|
103
|
+
dscnd = "wfile.dsid = '{}' ".format(dsid)
|
|
104
|
+
if not re.match(r'^\s*(ORDER|GROUP|HAVING|OFFSET|LIMIT)\s', condition, re.I): dscnd += 'AND '
|
|
105
|
+
return dscnd + condition # no where clause, append directly
|
|
106
|
+
else:
|
|
107
|
+
return "wfile.dsid = '{}'".format(dsid)
|
|
108
|
+
|
|
109
|
+
# insert one record into wfile and/or wfile_dsid
|
|
110
|
+
def pgadd_wfile(self, dsid, wfrec, logact = None, getid = None):
|
|
111
|
+
if logact is None: logact = self.LOGERR
|
|
112
|
+
record = {'wfile' : wfrec['wfile'],
|
|
113
|
+
'dsid' : (wfrec['dsid'] if 'dsid' in wfrec else dsid)}
|
|
114
|
+
wret = self.pgadd('wfile', record, logact, 'wid')
|
|
115
|
+
if wret:
|
|
116
|
+
record = self.wfile2wdsid(wfrec, wret)
|
|
117
|
+
self.pgadd('wfile_' + dsid, record, logact|self.ADDTBL)
|
|
118
|
+
if logact&self.AUTOID or getid:
|
|
119
|
+
return wret
|
|
120
|
+
else:
|
|
121
|
+
return 1 if wret else 0
|
|
122
|
+
|
|
123
|
+
# insert multiple records into wfile and/or wfile_dsid
|
|
124
|
+
def pgmadd_wfile(self, dsid, wfrecs, logact = None, getid = None):
|
|
125
|
+
if logact is None: logact = self.LOGERR
|
|
126
|
+
records = {'wfile' : wfrecs['wfile'],
|
|
127
|
+
'dsid' : (wfrecs['dsid'] if 'dsid' in wfrecs else [dsid]*len(wfrecs['wfile']))}
|
|
128
|
+
wret = self.pgmadd('wfile', records, logact, 'wid')
|
|
129
|
+
wcnt = wret if isinstance(wret, int) else len(wret)
|
|
130
|
+
if wcnt:
|
|
131
|
+
records = self.wfile2wdsid(wfrecs, wret)
|
|
132
|
+
self.pgmadd('wfile_' + dsid, records, logact|self.ADDTBL)
|
|
133
|
+
if logact&self.AUTOID or getid:
|
|
134
|
+
return wret
|
|
135
|
+
else:
|
|
136
|
+
return wcnt
|
|
137
|
+
|
|
138
|
+
# update one or multiple rows in wfile and/or wfile_dsid
|
|
139
|
+
# exclude dsid in condition
|
|
140
|
+
def pgupdt_wfile(self, dsid, wfrec, condition, logact = None):
|
|
141
|
+
if logact is None: logact = self.LOGERR
|
|
142
|
+
record = self.trim_wfile_fields(wfrec)
|
|
143
|
+
if record:
|
|
144
|
+
wret = self.pgupdt('wfile', record, self.get_dsid_condition(dsid, condition), logact)
|
|
145
|
+
else:
|
|
146
|
+
wret = 1
|
|
147
|
+
if wret:
|
|
148
|
+
record = self.wfile2wdsid(wfrec)
|
|
149
|
+
if record: wret = self.pgupdt("wfile_" + dsid, record, condition, logact|self.ADDTBL)
|
|
150
|
+
return wret
|
|
151
|
+
|
|
152
|
+
# update one row in wfile and/or wfile_dsid with dsid change
|
|
153
|
+
# exclude dsid in condition
|
|
154
|
+
def pgupdt_wfile_dsid(self, dsid, odsid, wfrec, wid, logact = None):
|
|
155
|
+
if logact is None: logact = self.LOGERR
|
|
156
|
+
record = self.trim_wfile_fields(wfrec)
|
|
157
|
+
cnd = 'wid = {}'.format(wid)
|
|
158
|
+
if record:
|
|
159
|
+
wret = self.pgupdt('wfile', record, cnd, logact)
|
|
160
|
+
else:
|
|
161
|
+
wret = 1
|
|
162
|
+
if wret:
|
|
163
|
+
record = self.wfile2wdsid(wfrec)
|
|
164
|
+
tname = 'wfile_' + dsid
|
|
165
|
+
doupdt = True
|
|
166
|
+
if odsid and odsid != dsid:
|
|
167
|
+
oname = 'wfile_' + odsid
|
|
168
|
+
pgrec = self.pgget(oname, '*', cnd, logact|self.ADDTBL)
|
|
169
|
+
if pgrec:
|
|
170
|
+
for fld in record:
|
|
171
|
+
pgrec[fld] = record[fld]
|
|
172
|
+
wret = self.pgadd(tname, pgrec, logact|self.ADDTBL)
|
|
173
|
+
if wret: self.pgdel(oname, cnd, logact)
|
|
174
|
+
doupdt = False
|
|
175
|
+
if doupdt and record:
|
|
176
|
+
wret = self.pgupdt(tname, record, cnd, logact|self.ADDTBL)
|
|
177
|
+
return wret
|
|
178
|
+
|
|
179
|
+
# delete one or multiple rows in wfile and/or wfile_dsid, and add the record(s) into wfile_delete
|
|
180
|
+
# exclude dsid in conidtion
|
|
181
|
+
def pgdel_wfile(self, dsid, condition, logact = None):
|
|
182
|
+
if logact is None: logact = self.LOGERR
|
|
183
|
+
pgrecs = self.pgmget_wfile(dsid, '*', condition, logact|self.ADDTBL)
|
|
184
|
+
wret = self.pgdel('wfile', self.get_dsid_condition(dsid, condition), logact)
|
|
185
|
+
if wret: self.pgdel("wfile_" + dsid, condition, logact)
|
|
186
|
+
if wret and pgrecs: self.pgmadd('wfile_delete', pgrecs, logact)
|
|
187
|
+
return wret
|
|
188
|
+
|
|
189
|
+
# delete one or multiple rows in sfile, and add the record(s) into sfile_delete
|
|
190
|
+
def pgdel_sfile(self, condition, logact = None):
|
|
191
|
+
if logact is None: logact = self.LOGERR
|
|
192
|
+
pgrecs = self.pgmget('sfile', '*', condition, logact)
|
|
193
|
+
sret = self.pgdel('sfile', condition, logact)
|
|
194
|
+
if sret and pgrecs: self.pgmadd('sfile_delete', pgrecs, logact)
|
|
195
|
+
return sret
|
|
196
|
+
|
|
197
|
+
# update one or multiple rows in wfile and/or wfile_dsid for multiple dsid
|
|
198
|
+
# exclude dsid in condition
|
|
199
|
+
def pgupdt_wfile_dsids(self, dsid, dsids, brec, bcnd, logact = None):
|
|
200
|
+
if logact is None: logact = self.LOGERR
|
|
201
|
+
record = self.trim_wfile_fields(brec)
|
|
202
|
+
if record:
|
|
203
|
+
wret = self.pgupdt("wfile", record, bcnd, logact)
|
|
204
|
+
else:
|
|
205
|
+
wret = 1
|
|
206
|
+
if wret:
|
|
207
|
+
record = self.wfile2wdsid(brec)
|
|
208
|
+
if record:
|
|
209
|
+
wret = 0
|
|
210
|
+
dids = [dsid]
|
|
211
|
+
if dsids: dids.extend(dsids.split(','))
|
|
212
|
+
for did in dids:
|
|
213
|
+
wret += self.pgupdt("wfile_" + did, record, bcnd, logact|self.ADDTBL)
|
|
214
|
+
return wret
|
|
215
|
+
|
|
216
|
+
# get one record from wfile or wfile_dsid
|
|
217
|
+
# exclude dsid in fields and condition
|
|
218
|
+
def pgget_wfile(self, dsid, fields, condition, logact = None):
|
|
219
|
+
if logact is None: logact = self.LOGERR
|
|
220
|
+
tname = "wfile_" + dsid
|
|
221
|
+
flds = fields.replace('wfile.', tname + '.')
|
|
222
|
+
cnd = condition.replace('wfile.', tname + '.')
|
|
223
|
+
record = self.pgget(tname, flds, cnd, logact|self.ADDTBL)
|
|
224
|
+
if record and flds == '*': record['dsid'] = dsid
|
|
225
|
+
return record
|
|
226
|
+
|
|
227
|
+
# get one record from wfile or wfile_dsid joing other tables
|
|
228
|
+
# exclude dsid in fields and condition
|
|
229
|
+
def pgget_wfile_join(self, dsid, tjoin, fields, condition, logact = None):
|
|
230
|
+
if logact is None: logact = self.LOGERR
|
|
231
|
+
tname = "wfile_" + dsid
|
|
232
|
+
flds = fields.replace('wfile.', tname + '.')
|
|
233
|
+
jname = tname + ' ' + tjoin.replace('wfile.', tname + '.')
|
|
234
|
+
cnd = condition.replace('wfile.', tname + '.')
|
|
235
|
+
record = self.pgget(jname, flds, cnd, logact|self.ADDTBL)
|
|
236
|
+
if record and flds == '*': record['dsid'] = dsid
|
|
237
|
+
return record
|
|
238
|
+
|
|
239
|
+
# get multiple records from wfile or wfile_dsid
|
|
240
|
+
# exclude dsid in fields and condition
|
|
241
|
+
def pgmget_wfile(self, dsid, fields, condition, logact = None):
|
|
242
|
+
if logact is None: logact = self.LOGERR
|
|
243
|
+
tname = "wfile_" + dsid
|
|
244
|
+
flds = fields.replace('wfile.', tname + '.')
|
|
245
|
+
cnd = condition.replace('wfile.', tname + '.')
|
|
246
|
+
records = self.pgmget(tname, flds, cnd, logact|self.ADDTBL)
|
|
247
|
+
if records and flds == '*': records['dsid'] = [dsid]*len(records['wid'])
|
|
248
|
+
return records
|
|
249
|
+
|
|
250
|
+
# get multiple records from wfile or wfile_dsid joining other tables
|
|
251
|
+
# exclude dsid in fields and condition
|
|
252
|
+
def pgmget_wfile_join(self, dsid, tjoin, fields, condition, logact = None):
|
|
253
|
+
if logact is None: logact = self.LOGERR
|
|
254
|
+
tname = "wfile_" + dsid
|
|
255
|
+
flds = fields.replace('wfile.', tname + '.')
|
|
256
|
+
jname = tname + ' ' + tjoin.replace('wfile.', tname + '.')
|
|
257
|
+
cnd = condition.replace('wfile.', tname + '.')
|
|
258
|
+
records = self.pgmget(jname, flds, cnd, logact|self.ADDTBL)
|
|
259
|
+
if records and flds == '*': records['dsid'] = [dsid]*len(records['wid'])
|
|
260
|
+
return records
|