@@ -16,6 +16,7 @@ class TSInfo(object):
1616 # As of RedisTimeseries >= v1.4 max_samples_per_chunk is deprecated in favor of chunk_size
1717 max_samples_per_chunk = None
1818 chunk_size = None
19+ duplicate_policy = None
1920
2021
2122 def __init__ (self , args ):
@@ -34,6 +35,10 @@ def __init__(self, args):
3435 self .chunk_size = self .max_samples_per_chunk * 16 # backward compatible changes
3536 if 'chunkSize' in response :
3637 self .chunk_size = response ['chunkSize' ]
38+ if 'duplicatePolicy' in response :
39+ self .duplicate_policy = response ['duplicatePolicy' ]
40+ if type (self .duplicate_policy ) == bytes :
41+ self .duplicate_policy = self .duplicate_policy .decode ()
3742
3843def list_to_dict (aList ):
3944 return {nativestr (aList [i ][0 ]):nativestr (aList [i ][1 ])
@@ -163,7 +168,15 @@ def appendChunkSize(params, chunk_size):
163168 if chunk_size is not None :
164169 params .extend (['CHUNK_SIZE' , chunk_size ])
165170
166- def create (self , key , retention_msecs = None , uncompressed = False , labels = {}, chunk_size = None ):
171+ @staticmethod
172+ def appendDuplicatePolicy (params , command , duplicate_policy ):
173+ if duplicate_policy is not None :
174+ if command == 'TS.ADD' :
175+ params .extend (['ON_DUPLICATE' , duplicate_policy ])
176+ else :
177+ params .extend (['DUPLICATE_POLICY' , duplicate_policy ])
178+
179+ def create (self , key , ** kwargs ):
167180 """
168181 Create a new time-series.
169182
@@ -177,28 +190,45 @@ def create(self, key, retention_msecs=None, uncompressed=False, labels={}, chunk
177190 labels: Set of label-value pairs that represent metadata labels of the key.
178191 chunk_size: Each time-serie uses chunks of memory of fixed size for time series samples.
179192 You can alter the default TSDB chunk size by passing the chunk_size argument (in Bytes).
193+ duplicate_policy: since RedisTimeSeries v1.4 you can specify the duplicate sample policy ( Configure what to do on duplicate sample. )
194+ Can be one of:
195+ - 'block': an error will occur for any out of order sample
196+ - 'first': ignore the new value
197+ - 'last': override with latest value
198+ - 'min': only override if the value is lower than the existing value
199+ - 'max': only override if the value is higher than the existing value
200+ When this is not set, the server-wide default will be used.
180201 """
202+ retention_msecs = kwargs .get ('retention_msecs' , None )
203+ uncompressed = kwargs .get ('uncompressed' , False )
204+ labels = kwargs .get ('labels' , {})
205+ chunk_size = kwargs .get ('chunk_size' , None )
206+ duplicate_policy = kwargs .get ('duplicate_policy' , None )
181207 params = [key ]
182208 self .appendRetention (params , retention_msecs )
183209 self .appendUncompressed (params , uncompressed )
184210 self .appendChunkSize (params , chunk_size )
211+ self .appendDuplicatePolicy (params , self .CREATE_CMD , duplicate_policy )
185212 self .appendLabels (params , labels )
186213
187214 return self .redis .execute_command (self .CREATE_CMD , * params )
188215
189- def alter (self , key , retention_msecs = None , labels = {} ):
216+ def alter (self , key , ** kwargs ):
190217 """
191218 Update the retention, labels of an existing key. The parameters
192219 are the same as TS.CREATE.
193220 """
221+ retention_msecs = kwargs .get ('retention_msecs' , None )
222+ labels = kwargs .get ('labels' , {})
223+ duplicate_policy = kwargs .get ('duplicate_policy' , None )
194224 params = [key ]
195225 self .appendRetention (params , retention_msecs )
226+ self .appendDuplicatePolicy (params , self .ALTER_CMD , duplicate_policy )
196227 self .appendLabels (params , labels )
197228
198229 return self .redis .execute_command (self .ALTER_CMD , * params )
199230
200- def add (self , key , timestamp , value , retention_msecs = None ,
201- uncompressed = False , labels = {}, chunk_size = None ):
231+ def add (self , key , timestamp , value , ** kwargs ):
202232 """
203233 Append (or create and append) a new sample to the series.
204234
@@ -214,11 +244,25 @@ def add(self, key, timestamp, value, retention_msecs=None,
214244 labels: Set of label-value pairs that represent metadata labels of the key.
215245 chunk_size: Each time-serie uses chunks of memory of fixed size for time series samples.
216246 You can alter the default TSDB chunk size by passing the chunk_size argument (in Bytes).
247+ duplicate_policy: since RedisTimeSeries v1.4 you can specify the duplicate sample policy ( Configure what to do on duplicate sample. )
248+ Can be one of:
249+ - 'block': an error will occur for any out of order sample
250+ - 'first': ignore the new value
251+ - 'last': override with latest value
252+ - 'min': only override if the value is lower than the existing value
253+ - 'max': only override if the value is higher than the existing value
254+ When this is not set, the server-wide default will be used.
217255 """
256+ retention_msecs = kwargs .get ('retention_msecs' , None )
257+ uncompressed = kwargs .get ('uncompressed' , False )
258+ labels = kwargs .get ('labels' , {})
259+ chunk_size = kwargs .get ('chunk_size' , None )
260+ duplicate_policy = kwargs .get ('duplicate_policy' , None )
218261 params = [key , timestamp , value ]
219262 self .appendRetention (params , retention_msecs )
220263 self .appendUncompressed (params , uncompressed )
221264 self .appendChunkSize (params , chunk_size )
265+ self .appendDuplicatePolicy (params , self .ADD_CMD , duplicate_policy )
222266 self .appendLabels (params , labels )
223267
224268 return self .redis .execute_command (self .ADD_CMD , * params )
@@ -237,8 +281,7 @@ def madd(self, ktv_tuples):
237281
238282 return self .redis .execute_command (self .MADD_CMD , * params )
239283
240- def incrby (self , key , value , timestamp = None , retention_msecs = None ,
241- uncompressed = False , labels = {}, chunk_size = None ):
284+ def incrby (self , key , value , ** kwargs ):
242285 """
243286 Increment (or create an time-series and increment) the latest sample's of a series.
244287 This command can be used as a counter or gauge that automatically gets history as a time series.
@@ -256,6 +299,11 @@ def incrby(self, key, value, timestamp=None, retention_msecs=None,
256299 chunk_size: Each time-serie uses chunks of memory of fixed size for time series samples.
257300 You can alter the default TSDB chunk size by passing the chunk_size argument (in Bytes).
258301 """
302+ timestamp = kwargs .get ('timestamp' , None )
303+ retention_msecs = kwargs .get ('retention_msecs' , None )
304+ uncompressed = kwargs .get ('uncompressed' , False )
305+ labels = kwargs .get ('labels' , {})
306+ chunk_size = kwargs .get ('chunk_size' , None )
259307 params = [key , value ]
260308 self .appendTimestamp (params , timestamp )
261309 self .appendRetention (params , retention_msecs )
@@ -265,8 +313,7 @@ def incrby(self, key, value, timestamp=None, retention_msecs=None,
265313
266314 return self .redis .execute_command (self .INCRBY_CMD , * params )
267315
268- def decrby (self , key , value , timestamp = None , retention_msecs = None ,
269- uncompressed = False , labels = {}, chunk_size = None ):
316+ def decrby (self , key , value , ** kwargs ):
270317 """
271318 Decrement (or create an time-series and decrement) the latest sample's of a series.
272319 This command can be used as a counter or gauge that automatically gets history as a time series.
@@ -284,6 +331,11 @@ def decrby(self, key, value, timestamp=None, retention_msecs=None,
284331 chunk_size: Each time-serie uses chunks of memory of fixed size for time series samples.
285332 You can alter the default TSDB chunk size by passing the chunk_size argument (in Bytes).
286333 """
334+ timestamp = kwargs .get ('timestamp' , None )
335+ retention_msecs = kwargs .get ('retention_msecs' , None )
336+ uncompressed = kwargs .get ('uncompressed' , False )
337+ labels = kwargs .get ('labels' , {})
338+ chunk_size = kwargs .get ('chunk_size' , None )
287339 params = [key , value ]
288340 self .appendTimestamp (params , timestamp )
289341 self .appendRetention (params , retention_msecs )
0 commit comments