diff --git a/CHANGELOG.md b/CHANGELOG.md index 09bd51835c93bf18eb3644e296082bacf0a9c043..b93e013a03f5c716bad9f9337188f8715ac3c9c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added ### +* Added examples for complex data models to documentation * extended apiutils with `resolve_reference(Property)` * is_reference function for Properties diff --git a/src/caosdb/yamlapi.py b/src/caosdb/yamlapi.py index b2e527983cbbeca2ee71a63e87f487d24d7c0301..9a69a5276804727084af65c6568b22833e8be596 100644 --- a/src/caosdb/yamlapi.py +++ b/src/caosdb/yamlapi.py @@ -73,6 +73,14 @@ def dict_to_xml(d): def yaml_to_xml(yamlstr): + """Load a yaml document from yamlstr and converts it to XML. + + Parameters + ---------- + yamlstr : str + The string to load the yaml document from. + + """ return dict_to_xml(yaml.load(yamlstr)) diff --git a/src/doc/tutorials/complex_data_models.rst b/src/doc/tutorials/complex_data_models.rst new file mode 100644 index 0000000000000000000000000000000000000000..0fa868e78bb45a2905dc99392a3a28a9832d369e --- /dev/null +++ b/src/doc/tutorials/complex_data_models.rst @@ -0,0 +1,76 @@ +Complex Data Models +------------------- + +With CaosDB it is possible to create very complex data models. + +E.g. it is possible to add properties to properties to cover complex relations +in data management workflows. + +One example for a use case is meta data that is added to very specific properties of +datasets, e.g. data privacy information can be added to properties which themselves +could already be considered meta data of a dataset. + +The example below tries to cover some complex cases for data models: + +Examples +-------- + +.. code-block:: python3 + + import caosdb as db + + # Create two record types with descriptions: + rt1 = db.RecordType(name="TypeA", description="The first type") + rt2 = db.RecordType(name="TypeB", description="The second type") + + # Create a record using the first record type as parent: + r1 = db.Record(name="Test_R_1", description="A record") + r1.add_parent(rt1) + + # Create two files (the files named test.txt and testfile2.txt should exist in the + # current working directory: + f1 = db.File(name="Test file", path="/test.txt", file="test.txt") + f2 = db.File(name="Test file 2", path="/testfile2.txt", file="testfile2.txt") + + # Create two properties with different data types: + p1 = db.Property(name="TestFileProperty", datatype=db.FILE) + p2 = db.Property(name="TestDoubleProperty", datatype=db.DOUBLE, unit="m") + p3 = db.Property(name="TestIntegerProperty", datatype=db.INTEGER, unit="s") + + # Create a reference property that points to records of record type 2: + p4 = db.Property(name="TestReferenceProperty", datatype=rt2) + + # Create a complex record: + r2 = db.Record(name="Test_R_2", description="A second record") + r2.add_parent(rt2) + r2.add_property(rt1, value=r1) # this is a reference to the first record type + r2.add_property(p1, value=f1) # this is a reference to the first file + r2.add_property(p2, value=24.8) # this is a double property with a value + r2.add_property(p3, value=1) # this is an integer property with a value + + # Very complex part of the data model: + # Case 1: File added to another file + f2.add_property(p1, value=f1) # this adds a file property with value first file + # to the second file + + # Case 2: Property added to a property + p2.add_property(p3, value=27) # this adds an integer property with value 27 to the + # double property + + # Case 3: Reference property added to a property + # The property p2 now has two sub properties, one is pointing to + # record p2 which itself has the property p2, therefore this can be + # considered a loop in the data model. + p2.add_property(p4, value=r2) # this adds a reference property pointing to + # record 2 to the double property + + # Insert a container containing all the newly created entities: + c = db.Container().extend([rt1, rt2, r1, r2, f1, p1, p2, p3, f2, p4]) + c.insert() + + # Useful for testing: wait until the user presses a key + # Meanwhile have a look at the WebUI: You can e.g. query "FIND Test*" to view + # all the entities created here and see the relations and links between them. + b = input("Press any key to cleanup.") + # cleanup everything after the user presses any button. + c.delete() diff --git a/src/doc/tutorials/index.rst b/src/doc/tutorials/index.rst index 3889edb8f47e973cc7ae25c9134d75cfeab95f65..79068e9201498c87b2eb61b4ffbea0969845b404 100644 --- a/src/doc/tutorials/index.rst +++ b/src/doc/tutorials/index.rst @@ -15,4 +15,5 @@ advanced usage of the Python client. Data-Insertion errors data-model-interface - + complex_data_models +