Namespaces: Organizing Keys
The Filing Cabinet Analogy
Imagine a giant filing cabinet at school. Instead of throwing all papers into one big pile, you organize them into labeled folders:
The folder name (math, science, english) is the namespace. The : between the folder name and the paper name is the separator. It keeps things organized so that math:homework1 and english:homework1 don't get mixed up.
Creating a Namespace
from pykv import BasicStore, Namespace
store = BasicStore()
# Create namespaces (like labeled folders)
users = Namespace(store, "users")
posts = Namespace(store, "posts")
Using Namespaces
# Store data through the namespace
users.set("alice", {"role": "admin"})
users.set("bob", {"role": "member"})
posts.set("1", "Hello, world!")
# Retrieve data -- you only need the short key
users.get("alice") # {"role": "admin"}
posts.get("1") # "Hello, world!"
Behind the scenes, the keys in the store are:
The : is added for you. You can write it yourself if you like --
Namespace(store, "users:") is exactly the same folder as
Namespace(store, "users").
Listing Keys in a Namespace
Isolation
Namespaces keep groups separate. Clearing one namespace doesn't touch others:
Why Use Namespaces?
When multiple parts of your program share one store, namespaces prevent key collisions:
# Without namespaces: DANGER! Keys collide!
store.set("count", 42) # Game module
store.set("count", 7) # Chat module -- oops, overwrote game data!
# With namespaces: Safe!
game = Namespace(store, "game")
chat = Namespace(store, "chat")
game.set("count", 42)
chat.set("count", 7) # No collision!
Folders Inside Folders
A folder can sit inside another folder. Use : in the namespace's
name to nest it:
users = Namespace(store, "users")
admins = Namespace(store, "users:admin") # a folder inside "users"
users.set("bob", {"role": "member"})
admins.set("alice", {"role": "admin"})
In the store, that's:
Each folder only sees its own papers. The admin folder inside users
is a separate folder, so users doesn't count what's inside it:
users.keys() # ["bob"] (not "admin:alice"!)
admins.keys() # ["alice"]
users.clear() # empties "users" -- "users:admin" keeps alice
The Separator Rule
There is one rule that makes all of this work:
A key inside a namespace can never contain
:.
Here's why. Suppose the rule didn't exist, and the users folder filed
a paper called "admin:alice". Its full label would be
users: + admin:alice = users:admin:alice. But that's exactly the
label of alice in the users:admin folder! Two folders would be
sharing one paper, and writing in one would scribble over the other.
Two folders must never share a paper. With the rule, they can't:
the folder is always everything before the last :, and the paper
name is everything after it. Every label in the store belongs to exactly
one folder.
So PyKV refuses a key with : in it and tells you why:
from pykv import NamespaceError
users.set("admin:alice", 1)
# NamespaceError: Key 'admin:alice' contains ':', which separates folder names ...
If you wanted a folder inside users, make a nested namespace instead,
like Namespace(store, "users:admin") above.
A namespace's name can't be empty, either, and every part of it between
:s needs at least one character. Namespace(store, ""),
Namespace(store, ":") and Namespace(store, "users::admin") all raise
NamespaceError.
NamespaceError is a PyKVError, so except PyKVError: catches it too.
Upgrading from 0.2
Two things work differently since v0.3.0, and neither one raises an error, so watch out:
- The
:is now always added for you. A prefix written without one, likeNamespace(store, "cache_"), now filesxascache_:xinstead ofcache_x. - An old key with
:in it, likeusers:admin:alicewritten through theusersnamespace, now belongs to the nestedusers:adminfolder. Theusersfolder'skeys(),size()andclear()skip it; useNamespace(store, "users:admin")to reach it.