docs
0
# String Operations
1
2
Redis string data type operations providing full compatibility with Redis string commands. Strings are the most basic Redis data type and can store any binary data including text, numbers, and serialized objects up to 512MB in size.
3
4
## Capabilities
5
6
### Basic String Operations
7
8
Core string manipulation functions for setting, getting, and modifying string values.
9
10
```python { .api }
11
def set_(
12
self,
13
name: KeyT,
14
value: EncodableT,
15
ex: Optional[ExpiryT] = None,
16
px: Optional[ExpiryT] = None,
17
nx: bool = False,
18
xx: bool = False,
19
keepttl: bool = False,
20
get: bool = False,
21
exat: Optional[AbsExpiryT] = None,
22
pxat: Optional[AbsExpiryT] = None
23
) -> Optional[bytes]: ...
24
25
def get(self, name: KeyT) -> Optional[bytes]: ...
26
27
def mget(self, keys: Iterable[KeyT]) -> List[Optional[bytes]]: ...
28
29
def mset(self, mapping: Mapping[AnyKeyT, EncodableT]) -> ResponseT: ...
30
31
def msetnx(self, mapping: Mapping[AnyKeyT, EncodableT]) -> ResponseT: ...
32
33
def getset(self, name: KeyT, value: EncodableT) -> Optional[bytes]: ...
34
35
def getdel(self, name: KeyT) -> Optional[bytes]: ...
36
37
def getex(
38
self,
39
name: KeyT,
40
ex: Optional[ExpiryT] = None,
41
px: Optional[ExpiryT] = None,
42
exat: Optional[AbsExpiryT] = None,
43
pxat: Optional[AbsExpiryT] = None,
44
persist: bool = False
45
) -> Optional[bytes]: ...
46
```
47
48
### String Manipulation
49
50
Functions for modifying string content including range operations and concatenation.
51
52
```python { .api }
53
def append(self, key: KeyT, value: EncodableT) -> ResponseT: ...
54
55
def getrange(self, name: KeyT, start: int, end: int) -> ResponseT: ...
56
57
def setrange(self, name: KeyT, offset: int, value: EncodableT) -> ResponseT: ...
58
59
def strlen(self, name: KeyT) -> ResponseT: ...
60
61
def lcs(
62
self,
63
key1: KeyT,
64
key2: KeyT,
65
len: bool = False,
66
idx: bool = False,
67
minmatchlen: Optional[int] = None,
68
withmatchlen: bool = False
69
) -> Union[str, int, Dict[str, Any]]: ...
70
```
71
72
### Numeric Operations
73
74
String operations for numeric values including increment, decrement, and floating-point arithmetic.
75
76
```python { .api }
77
def incr(self, name: KeyT, amount: int = 1) -> ResponseT: ...
78
79
def incrby(self, name: KeyT, amount: int = 1) -> ResponseT: ...
80
81
def incrbyfloat(self, name: KeyT, amount: float = 1.0) -> ResponseT: ...
82
83
def decr(self, name: KeyT, amount: int = 1) -> ResponseT: ...
84
85
def decrby(self, name: KeyT, amount: int = 1) -> ResponseT: ...
86
```
87
88
### Conditional Set Operations
89
90
String setting operations with various conditions and expiration options.
91
92
```python { .api }
93
def setnx(self, name: KeyT, value: EncodableT) -> ResponseT: ...
94
95
def setex(self, name: KeyT, time: ExpiryT, value: EncodableT) -> ResponseT: ...
96
97
def psetex(self, name: KeyT, time_ms: ExpiryT, value: EncodableT) -> ResponseT: ...
98
```
99
100
## Usage Examples
101
102
### Basic String Operations
103
104
```python
105
import fakeredis
106
107
client = fakeredis.FakeRedis()
108
109
# Basic set and get
110
client.set('user:1:name', 'Alice')
111
name = client.get('user:1:name')
112
print(name.decode()) # 'Alice'
113
114
# Set with expiration (seconds)
115
client.set('session:abc123', 'user_data', ex=3600)
116
117
# Set with expiration (milliseconds)
118
client.set('temp:data', 'value', px=5000)
119
120
# Conditional set (only if key doesn't exist)
121
result = client.set('counter', '0', nx=True)
122
print(result) # True if set, None if key already exists
123
124
# Get and set atomically
125
old_value = client.getset('config:setting', 'new_value')
126
```
127
128
### Multiple Key Operations
129
130
```python
131
import fakeredis
132
133
client = fakeredis.FakeRedis()
134
135
# Set multiple keys at once
136
client.mset({
137
'user:1:name': 'Alice',
138
'user:1:email': 'alice@example.com',
139
'user:1:age': '30'
140
})
141
142
# Get multiple keys at once
143
values = client.mget(['user:1:name', 'user:1:email', 'user:1:age'])
144
for value in values:
145
if value:
146
print(value.decode())
147
148
# Set multiple keys only if none exist
149
result = client.msetnx({
150
'new:key1': 'value1',
151
'new:key2': 'value2'
152
})
153
print(result) # True if all keys were set, False if any already existed
154
```
155
156
### String Manipulation
157
158
```python
159
import fakeredis
160
161
client = fakeredis.FakeRedis()
162
163
# String concatenation
164
client.set('message', 'Hello')
165
new_length = client.append('message', ' World')
166
print(new_length) # 11
167
print(client.get('message').decode()) # 'Hello World'
168
169
# String length
170
length = client.strlen('message')
171
print(length) # 11
172
173
# Substring operations
174
client.set('text', 'Hello Redis World')
175
substring = client.getrange('text', 0, 4)
176
print(substring.decode()) # 'Hello'
177
178
# Replace part of string
179
client.setrange('text', 6, 'Python')
180
print(client.get('text').decode()) # 'Hello Python World'
181
```
182
183
### Numeric Operations
184
185
```python
186
import fakeredis
187
188
client = fakeredis.FakeRedis()
189
190
# Counter operations
191
client.set('counter', '0')
192
new_value = client.incr('counter')
193
print(new_value) # 1
194
195
# Increment by specific amount
196
new_value = client.incrby('counter', 5)
197
print(new_value) # 6
198
199
# Floating point operations
200
client.set('price', '19.99')
201
new_price = client.incrbyfloat('price', 5.01)
202
print(new_price) # 25.0
203
204
# Decrement operations
205
new_value = client.decr('counter')
206
print(new_value) # 5
207
208
new_value = client.decrby('counter', 3)
209
print(new_value) # 2
210
```
211
212
### Advanced String Operations
213
214
```python
215
import fakeredis
216
217
client = fakeredis.FakeRedis()
218
219
# Get with expiration update
220
client.set('cached_data', 'important_value', ex=60)
221
# Get and extend expiration
222
value = client.getex('cached_data', ex=300) # Extend to 5 minutes
223
224
# Get and delete atomically
225
value = client.getdel('temp_data')
226
# Key is now deleted, value contains the previous value
227
228
# Longest Common Subsequence
229
client.set('str1', 'abcde')
230
client.set('str2', 'ace')
231
lcs_result = client.lcs('str1', 'str2')
232
print(lcs_result) # 'ace'
233
234
# LCS with additional info
235
lcs_info = client.lcs('str1', 'str2', len=True, idx=True)
236
print(lcs_info) # Dictionary with matches and indices
237
```
238
239
### Conditional and Expiring Sets
240
241
```python
242
import fakeredis
243
244
client = fakeredis.FakeRedis()
245
246
# Set only if key doesn't exist
247
result = client.setnx('unique_id', 'generated_id_123')
248
print(result) # True if set, False if key already exists
249
250
# Set with expiration in seconds
251
client.setex('session_token', 1800, 'abc123def456') # Expires in 30 minutes
252
253
# Set with expiration in milliseconds
254
client.psetex('short_lived', 5000, 'temporary') # Expires in 5 seconds
255
256
# Advanced set with multiple options
257
result = client.set(
258
'cache_key',
259
'cached_value',
260
ex=3600, # Expire in 1 hour
261
nx=True, # Only if key doesn't exist
262
get=True # Return previous value
263
)
264
```
265
266
### Pattern: Distributed Counters
267
268
```python
269
import fakeredis
270
import threading
271
272
def worker(client, counter_key, worker_id):
273
for i in range(100):
274
count = client.incr(counter_key)
275
print(f"Worker {worker_id}: {count}")
276
277
client = fakeredis.FakeRedis()
278
client.set('global_counter', '0')
279
280
# Simulate multiple threads incrementing counter
281
threads = []
282
for i in range(5):
283
t = threading.Thread(target=worker, args=(client, 'global_counter', i))
284
threads.append(t)
285
t.start()
286
287
for t in threads:
288
t.join()
289
290
final_count = client.get('global_counter')
291
print(f"Final count: {final_count.decode()}") # Should be 500
292
```
293
294
### Pattern: Cache with Fallback
295
296
```python
297
import fakeredis
298
import time
299
300
client = fakeredis.FakeRedis()
301
302
def get_user_data(user_id):
303
cache_key = f'user:{user_id}:data'
304
305
# Try to get from cache first
306
cached = client.get(cache_key)
307
if cached:
308
return cached.decode()
309
310
# Simulate expensive database lookup
311
time.sleep(0.1)
312
user_data = f"User {user_id} profile data"
313
314
# Cache for 1 hour
315
client.setex(cache_key, 3600, user_data)
316
return user_data
317
318
# Usage
319
data1 = get_user_data('123') # Cache miss, slow
320
data2 = get_user_data('123') # Cache hit, fast
321
```