-
Notifications
You must be signed in to change notification settings - Fork 7
Adding condition values
=== Basic types: int, float, bool, string ===
To store basic types one of the fields should be used:
- ConditionType.STRING_FIELD
- ConditionType.INT_FIELD
- ConditionType.BOOL_FIELD
- ConditionType.FLOAT_FIELD
Lets example it:
# Create RCDBProvider provider object and connect it to DB db = RCDBProvider("sqlite:///example.db")db.create_condition_type("int_val", ConditionType.INT_FIELD) db.create_condition_type("float_val", ConditionType.FLOAT_FIELD) db.create_condition_type("bool_val", ConditionType.BOOL_FIELD) db.create_condition_type("string_val", ConditionType.STRING_FIELD)
db.add_condition(1, "int_val", 1000) db.add_condition(1, "float_val", 2.5) db.add_condition(1, "bool_val", True) db.add_condition(1, "string_val", "test test")
condition = db.get_condition(1, "int_val") print condition.value
condition = db.get_condition(1, "float_val") print condition.value
condition = db.get_condition(1, "bool_val") print condition.value
condition = db.get_condition(1, "string_val") print condition.value
The output:
1000 2.5 True test test=== Time information ===
A time information can be attached to any condition value. Standard python datetime is used for that: (Lets see the first example):
# Create condition type db.create_condition_type("my_val", ConditionType.INT_FIELD)db.add_condition(1, "my_val", 2000, datetime(2015, 10, 10, 15, 28, 12, 111111))
condition = db.get_condition(1, "my_val")
print condition print "value =", condition.value print "name =", condition.name print "time =", condition.time
The output is:
value = 2000 name = my_val time = 2015-10-10 15:28:12.111111If time is the only relevant information for a condition, then ConditionType.TIME_FIELD type can be used to create the condition type. In this case ''Condition.value'' field will have time information and time can be passed as value parameter of add_condition function:
db.create_condition_type("lunch_bell_rang", ConditionType.TIME_FIELD)time = datetime(2015, 9, 1, 14, 21, 01) db.add_condition(1, "lunch_bell_rang", time)
val = self.db.get_condition(1, "lunch_bell_rang") print val.value print val.time
The output is:
2015-09-01 14:21:01 2015-09-01 14:21:01Note that ''val.value'' and ''val.time'' are the same in this example.
=== Multiple values per run ===
To add many values of the same type, ''is_many_per_run'' parameter of ''create_condition_type'' function should be set to True. Then you are able to add many condition values per one run, but specifying time for each of them.
'''(!)''' if '''is_many_per_run=True''', then '''get_condition''' returns a list of Condition objects. Even if there is only one object selected.
Example
# Many condition values allowed for the run (is_many_per_run=True) # 1. If run has this condition, with the same value and actual_time the func. DOES NOTHING # 2. If run has this conditions but at different time, it adds this condition to DBdb.create_condition_type("multi", ConditionType.INT_FIELD)
time1 = datetime(2015,9,1,14,21,01, 222) time2 = datetime(2015,9,1,14,21,01, 333)
db.add_condition(1, "multi", 2222)
db.add_condition(1, "multi", 3333, time1) db.add_condition(1, "multi", 4444, time2)
results = db.get_condition(1, "multi")
print results values = [result.value for result in results] times = [result.time for result in results] print values print times
The output:
[, , ] [2222, 3333, 4444] [None, datetime(2015, 9, 1, 14, 21, 1, 222), datetime(2015, 9, 1, 14, 21, 1, 333)]=== Arrays and dictionaries ===
Multiple values per run are '''NOT''' intended to store arrays of data.
Best way to store arrays and dictionaries is serializing them to JSON. Use ConditionType.JSON_FIELD for that. RCDB conditions API doesn't provide mechanisms of converting objects to JSON and from JSON. For arrays it is done easily by json module.
The example from https://docs.python.org/2/library/json.html python 2.7 documentation:
>>> import json >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) '["foo", {"bar": ["baz", null, 1.0, 2]}]'json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') [u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
So, serialization is on your side. It is done to have a better control over serialization. This means that '''if condition type is JSON_FIELD, ''add_condition'' function awaits string''' and '''after you get condition back, Condition.value contains string'''.
Example:
import json from rcdb.provider import RCDBProvider from rcdb.model import ConditionTypedb = RCDBProvider("sqlite:///example.db")
db.create_condition_type("list_data", ConditionType.JSON_FIELD) db.create_condition_type("dict_data", ConditionType.JSON_FIELD)
list_to_store = [1, 2, 3] dict_to_store = {"x": 1, "y": 2, "z": 3}
db.add_condition(1, "list_data", json.dumps(list_to_store)) db.add_condition(1, "dict_data", json.dumps(dict_to_store))
restored_list = json.loads(db.get_condition(1, "list_data").value) restored_dict = json.loads(db.get_condition(1, "dict_data").value)
print restored_list print restored_dict
print restored_dict["x"] print restored_dict["y"] print restored_dict["z"]
The output is:
[1, 2, 3] {u'y': 2, u'x': 1, u'z': 3} 1 2 3
The example is located at
$RCDB_HOME/python/example_conditions_store_array.pyand can be run as: python $RCDB_HOME/python/create_empty_sqlite.py example.db python $RCDB_HOME/python/example_conditions_store_array.py
As one can mention unicode string is returned as unicode after json deserialization (look at u"x" instead of just "x"). It is not a problem if you just work with this array, because python acts seamlessly with unicode strings. As you can see in example, we use usual string "x" in restored_dict["x"] and it just works.
If it is a problem, there is a http://stackoverflow.com/questions/956867/how-to-get-string-objects-instead-of-unicode-ones-from-json-in-python stackoverlow question on that
Using pyYAML to deserialize to strings looks easy.
=== Custom python objects ===
To save custom python objects to database, jsonpickle package could be used. It is an open source project available via pip install. It is not shipped with RCDB at the moment.
from rcdb.provider import RCDBProvider from rcdb.model import ConditionType import jsonpickleclass Cat(object): def init(self, name): self.name = name self.mice_eaten = 1230
db = RCDBProvider("sqlite:///example.db")
db.create_condition_type("cat", ConditionType.JSON_FIELD)
cat = Cat('Alice') db.add_condition(1, "cat", jsonpickle.encode(cat))
condition = db.get_condition(1, "cat") loaded_cat = jsonpickle.decode(condition.value)
print "How cat is stored in DB:" print condition.value print "Deserialized cat:" print "name:", loaded_cat.name print "mice_eaten:", loaded_cat.mice_eaten
The result:
How cat is stored in DB: {"py/object": "__main__.Cat", "name": "Alice", "mice_eaten": 1230} Deserialized cat: name: Alice mice_eaten: 1230http://jsonpickle.github.io jsonpickle Documentation
jsonpickle installation:
system level:
pip install jsonpickleuser level:
pip install --user jsonpickle=== STRING_FIELD vs. JSON_FIELD vs. BLOB_FIELD ===
What if data doesn't fit into the string or JSON? There is ConditionType.BLOB_FIELD type.
Concise instruction is much like JSON:
- Set condition type as BLOB_FIELD
- You serialize object whatever you like
- Save it to DB as string
- Load from DB
- Deserialize whatever you like
But what is the difference between STRING_FIELD, JSON_FIELD and BLOB_FIELD?
There is no difference in terms of storing the data. A Condition class, same as a database table, has ''text_value'' field where text/string data is stored. The ONLY difference is how this fields are treated and presented in GUI.
-
'''STRING_FIELD''' - is considered to be a human readable string.
-
'''JSON_FIELD''' - is considered to be JSON, which is colored and formatted accordingly
-
'''BLOB_FIELD''' - is considered to be neither very readable string nor JSON. But it is still should converted to some string. And I hope it will never be used.
Getting started & basic usage:
- Installation
- Select values tutorial (python)
- Query syntax
- Add data (python)
- CLI Basics
RCDB Explained:
- Connection
- DB and APIs structure
- SQL examples
- Creating condition types
- Adding condition values
- Saving files
- SQLAlchemy
- Logging
- Performance
Command line tools:
DAQ: