"We assume that you are connected to the publicly available demo instance at demo.indiscale.com"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'caosdb.common.models.Record'>\n",
"<class 'caosdb.common.models.RecordType'>\n"
]
}
],
"source": [
"# loading the module with an alias\n",
"import caosdb as db\n",
"\n",
"# the most useful functions and constants can be accessed directly\n",
"# E.g. basic information about the LinkAhead instance to you are connected\n",
"#db.Info()\n",
"\n",
"# Or the query interface\n",
"response = db.execute_query(\"FIND RECORD Guitar\")\n",
"\n",
"# Or classes that represent LinkAhead objects \n",
"print(db.Record)\n",
"print(db.RecordType)\n",
"\n",
"# Currently it is necessary to force a login if annonymous users are allowed.\n",
"db.get_connection()._login()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's start with queries."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Queries\n",
"Queries work the same way as in the web interface. You simply provide the query string to the corresponding function. However, the result is not displayed as beautifully as in the web interface. That is why browsing through data is the strength of the web interface while the automated processing of data where you know the structure is the strength of the Python client."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<Entities>\n",
" <UserInfo>\n",
" </UserInfo>\n",
" <Record id=\"115\" name=\"My first guitar\">\n",
"As predicted, the text output of the query result is quite hard to read. So, how do we work with such results?"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"caosdb.common.models.Container"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(response)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As you can see the type of the returned object is `Container`. `Container`s are simply lists of LinkAhead objects with useful functions to interact with LinkAhead."
"Why did the second version work? In the web interface we do not realize it that easily, but there is only one thing that uniquely identifies Entities in LinkAhead: the id.\n",
"\n",
"In the xml output you see, that the properties have the ids 100 and 106. Often names of entities are also unique, but this is not guarenteed. Thus in many cases it is preferable or even necessary to use the id for identifying LinkAhead Entities. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ids can also come in handy when searching. Suppose you have some complicated condition for the object that you want"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'caosdb.common.models.Record'>\n",
"123\n"
]
}
],
"source": [
"# This condition is not that complicated and long but let's suppose it was.\n",
"record = db.execute_query(\"FIND Analysis with quality_factor=0.08\", unique=True)\n",
"# You can use unique=True when you only expect one result Entity. An error will be\n",
"# thrown if the number of results is unequal to 1 and the resulting object will be \n",
"# an Entity and not a Container\n",
"print(type(record))\n",
"print(record.id)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Using the id of the first query allows you to formulate a second query with a condition involving this object without including the potentially long and complicated subquery in this one:"
"Often we are interested in table like data for our processing. And the disentangling of the property values as above is a bit annoying. Thus there is a convenience function for that."
"If the files are large data files, it is often a better idea to only retrieve the path of the file and access them via a local mount."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"/reports/report_g_2019-023.pdf\n"
]
}
],
"source": [
"print(file.path)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Inserting Data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can insert data and change the data model via the Python Client. \n"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<RecordType id=\"142\" cuid=\"-1--0b12c17d-d4f5-4e99-aefb-6470030cb32f\" name=\"Flute\" description=\"Here you can provide a description of this recordtype\">\n",
" <Warning code=\"0\" description=\"Entity has no properties.\"/>\n",
"<RecordType id=\"142\" cuid=\"-1--0b12c17d-d4f5-4e99-aefb-6470030cb32f\" name=\"Flute\" description=\"Here you can provide a description of this recordtype\">\n",
"1. Create a new kind of Analysis. It is usually a good idea to prevent name collisions of RecordTypes (i.e. not two RecordTypes with the same name). Also users of one LinkAhead instance should coordinate their creation of RecordTypes and other data model changes. For example, it would be bad if there are two different RecordTypes with different names and properties for essentially the same thing created by two users that did not speak to each other and did not bother to look what exists... For the sake of this tutorial, create an Analysis with some unique suffix.\n",
"2. Create a Property that stores files; again with unique suffix in the name\n",
"3. Create and insert a Record with your new RecordType as parent, an description and the file with the histogram as property. (You might want to check [the wiki](https://gitlab.com/caosdb/caosdb/wikis/manuals/pylib/PyCaosDB#insertion-of-records-and-files) for information on File insertion). Furhermore, reference all Analysis Records that contributed a quality_factor to the histogram. You might also want to check the [List datatype](https://gitlab.com/caosdb/caosdb/wikis/manuals/pylib/PyCaosDB#define-a-property)."
"es = db.execute_query(\"FIND entity which was inserted by me today\")\n",
"es.delete()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.0"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
%% Cell type:markdown id: tags:
# General Introduction
%% Cell type:markdown id: tags:
We assume that you are connected to the publicly available demo instance at demo.indiscale.com
%% Cell type:code id: tags:
``` python
# loading the module with an alias
importcaosdbasdb
# the most useful functions and constants can be accessed directly
# E.g. basic information about the LinkAhead instance to you are connected
#db.Info()
# Or the query interface
response=db.execute_query("FIND RECORD Guitar")
# Or classes that represent LinkAhead objects
print(db.Record)
print(db.RecordType)
# Currently it is necessary to force a login if annonymous users are allowed.
db.get_connection()._login()
```
%% Output
<class 'caosdb.common.models.Record'>
<class 'caosdb.common.models.RecordType'>
%% Cell type:markdown id: tags:
Let's start with queries.
%% Cell type:markdown id: tags:
# Queries
Queries work the same way as in the web interface. You simply provide the query string to the corresponding function. However, the result is not displayed as beautifully as in the web interface. That is why browsing through data is the strength of the web interface while the automated processing of data where you know the structure is the strength of the Python client.
As predicted, the text output of the query result is quite hard to read. So, how do we work with such results?
%% Cell type:code id: tags:
``` python
type(response)
```
%% Output
caosdb.common.models.Container
%% Cell type:markdown id: tags:
As you can see the type of the returned object is `Container`. `Container`s are simply lists of LinkAhead objects with useful functions to interact with LinkAhead.
Why did the second version work? In the web interface we do not realize it that easily, but there is only one thing that uniquely identifies Entities in LinkAhead: the id.
In the xml output you see, that the properties have the ids 100 and 106. Often names of entities are also unique, but this is not guarenteed. Thus in many cases it is preferable or even necessary to use the id for identifying LinkAhead Entities.
%% Cell type:markdown id: tags:
Ids can also come in handy when searching. Suppose you have some complicated condition for the object that you want
%% Cell type:code id: tags:
``` python
# This condition is not that complicated and long but let's suppose it was.
record=db.execute_query("FIND Analysis with quality_factor=0.08",unique=True)
# You can use unique=True when you only expect one result Entity. An error will be
# thrown if the number of results is unequal to 1 and the resulting object will be
# an Entity and not a Container
print(type(record))
print(record.id)
```
%% Output
<class 'caosdb.common.models.Record'>
123
%% Cell type:markdown id: tags:
Using the id of the first query allows you to formulate a second query with a condition involving this object without including the potentially long and complicated subquery in this one:
%% Cell type:code id: tags:
``` python
query="FIND Guitar WHICH IS REFERENCED BY {id}".format(id=record.id)
Often we are interested in table like data for our processing. And the disentangling of the property values as above is a bit annoying. Thus there is a convenience function for that.
1. Create a new kind of Analysis. It is usually a good idea to prevent name collisions of RecordTypes (i.e. not two RecordTypes with the same name). Also users of one LinkAhead instance should coordinate their creation of RecordTypes and other data model changes. For example, it would be bad if there are two different RecordTypes with different names and properties for essentially the same thing created by two users that did not speak to each other and did not bother to look what exists... For the sake of this tutorial, create an Analysis with some unique suffix.
2. Create a Property that stores files; again with unique suffix in the name
3. Create and insert a Record with your new RecordType as parent, an description and the file with the histogram as property. (You might want to check [the wiki](https://gitlab.com/caosdb/caosdb/wikis/manuals/pylib/PyCaosDB#insertion-of-records-and-files) for information on File insertion). Furhermore, reference all Analysis Records that contributed a quality_factor to the histogram. You might also want to check the [List datatype](https://gitlab.com/caosdb/caosdb/wikis/manuals/pylib/PyCaosDB#define-a-property).