Skip to content
imagedb_objects.ipynb 10.9 KiB
Newer Older
Marco Frailis's avatar
Marco Frailis committed
   "cell_type": "markdown",
   "metadata": {},
   "source": [
Marco Frailis's avatar
Marco Frailis committed
    "# Data insertion and retrieval with Django models\n",
Marco Frailis's avatar
Marco Frailis committed
    "In the following we show some examples in order to perform insertions and retrievals of metadata "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
Marco Frailis's avatar
Marco Frailis committed
    "from imagedb.models import Instrument\n",
    "\n",
    "instrument = Instrument.objects.get(instrumentName='NISP')\n",
    "\n",
    "print(instrument.telescopeName)\n"
Marco Frailis's avatar
Marco Frailis committed
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Creating new objects\n",
    "\n",
    "In the following we will create a NispRawFrame object. Since the NispRawFrame must have also a DataCotainer (i.e. a file to reference to), we first create a DataContainer instance.\n",
    "\n",
    "We can see also that the fields that we have defined as composite fields provide some synctactic sugar when we initialize them with simple dictionaries."
   ]
  },
  {
   "cell_type": "code",
   "metadata": {},
   "outputs": [],
   "source": [
Marco Frailis's avatar
Marco Frailis committed
    "from imagedb.models import ImageType, Pointing, NispDetector, DataContainer, NispRawFrame\n",
    "\n",
    "from datetime import datetime\n",
Marco Frailis's avatar
Marco Frailis committed
    "\n",
    "dataFile = DataContainer(\n",
    "  fileFormat = 'fits',\n",
    "  formatIdentifier = 'le1.nisprawframe',\n",
    "  formatVersion = '1.0',\n",
Marco Frailis's avatar
Marco Frailis committed
    "  url = \"http://ia2-owncloud.oats.inaf.it/fake/7ff2f203/data/EUC_LE1_NISP_53892-Y-1_20170712T155430.1Z_00.00.fits\"\n",
Marco Frailis's avatar
Marco Frailis committed
    ")\n",
    "\n",
    "# We have to save the data container to the DB before assigning it to a NispRawFrame\n",
    "dataFile.save()\n",
    "\n",
    "image = NispRawFrame(exposureTime = 105,\n",
    "                     imgNumber = 16,\n",
    "                     naxis1 = 2040,\n",
    "                     naxis2 = 2040,\n",
    "                     imageType = {'category':'SCIENCE', \n",
    "                                  'firstType':'OBJECT', \n",
    "                                  'secondType':'STD'},\n",
    "                     observationDateTime = datetime.strptime(\"2025-06-21T18:27:23.000001\", \n",
    "                                                             \"%Y-%m-%dT%H:%M:%S.%f\"),\n",
Marco Frailis's avatar
Marco Frailis committed
    "                     observationId = 53892,\n",
    "                     ditherNumber = 1,\n",
    "                     instrument = instrument,\n",
    "                     commandedPointing = {'rightAscension':8.48223045516,\n",
    "                                          'declination':8.48223045516,\n",
Marco Frailis's avatar
Marco Frailis committed
    "                                          'orientation':64.8793517547},\n",
    "                     filterWheelPosition = \"Y\",\n",
    "                     grismWheelPosition = \"OPEN\"\n",
Marco Frailis's avatar
Marco Frailis committed
    "                    )\n",
    "\n",
    "\n",
    "\n",
    "image.frameFile = dataFile"
Marco Frailis's avatar
Marco Frailis committed
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before saving an object, its surrogate key is still empty, i.e. equal to None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
Marco Frailis's avatar
Marco Frailis committed
   "source": [
    "print(image.id)\n",
    "image.save()\n",
    "print(image.id)"
   ]
  },
  {
   "cell_type": "code",
Marco Frailis's avatar
Marco Frailis committed
   "metadata": {
    "scrolled": true
   },
Marco Frailis's avatar
Marco Frailis committed
    "# We can start creating a detector\n",
    "\n",
    "d11 = NispDetector(detectorId = \"11\", gain = 1.0, readoutNoise = 0.0, rawFrame = image)\n",
    "d11.save()\n",
    "\n",
Marco Frailis's avatar
Marco Frailis committed
    "# Or we can use the create() in order to create and save immediately the new object\n",
    "NispDetector.objects.create(detectorId = \"12\", gain = 1.0, readoutNoise = 0.0, rawFrame = image)\n",
    "\n",
    "# or we can create the detector starting from the NispRawFrame, using the reversed relationship,\n",
    "# using again the create method\n",
Marco Frailis's avatar
Marco Frailis committed
    "\n",
    "image.detectors.create(\n",
Marco Frailis's avatar
Marco Frailis committed
    "  detectorId = \"13\",\n",
Marco Frailis's avatar
Marco Frailis committed
    "  gain = 1.0,\n",
    "  readoutNoise = 0.0\n",
    ")"
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Objects retrieval\n",
    "\n",
    "To retrieve objects from your database, construct a **QuerySet** via a **Manager** on your model class. \n",
    "\n",
    "A **QuerySet** represents a collection of objects from your database. It can have zero, one or many filters. Filters narrow down the query results based on the given parameters. In SQL terms, a **QuerySet** equates to a **SELECT** statement, and a **filter** is a limiting clause such as **WHERE** or **LIMIT**.\n",
    "\n",
    "You get a **QuerySet** by using your model’s **Manager**. Each model has at least one Manager, and it’s called **objects** by default.\n",
    "\n",
    "The simplest way to retrieve objects from a table is to get all of them. To do this, use the **all()** method on a **Manager**:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "len(NispRawFrame.objects.all())"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "But usually we want to filter the results. For this purpose we can use the **filter** method, both provided by the **Manager** and the **QuerySet**\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Retrieving all frames with observation id 53877 and filter Y\n",
    "# and ordering the results by the ditherNumber\n",
    "\n",
    "result = NispRawFrame.objects.filter(observationId=53877, \n",
    "                                     filterWheelPosition='Y').order_by('ditherNumber')\n",
    "\n",
    "for obj in result:\n",
    "    print(obj.observationId, obj.filterWheelPosition, obj.ditherNumber)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also limit the number of results of a **QuerySet**, using the Python array-slice syntax:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from datetime import datetime\n",
    "\n",
    "# Retrieving all NISP raw frames with observation date and time \n",
    "# greater then or equal to 2026-06-22T17:00\n",
    "len(NispRawFrame.objects.filter(observationDateTime__gte=datetime(2025,6,22,17,0)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Now limiting the result to 5 items\n",
    "\n",
    "len(NispRawFrame.objects.filter(observationDateTime__gte=datetime(2025,6,22,17,0))[:5])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Keyword argument queries – in filter(), etc. – are “AND”ed together. If you need to execute more complex queries (for example, queries with OR statements), you can use **Q objects**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Now retrieving all frames with observation ids 53877 and 54349 and filter H\n",
    "from django.db.models import Q\n",
    "\n",
    "result = NispRawFrame.objects.filter(Q(observationId=53877) | Q(observationId=54349), \n",
    "                                     filterWheelPosition='H').order_by('observationId', 'ditherNumber')\n",
    "\n",
    "for obj in result:\n",
    "    print(obj.observationId, obj.filterWheelPosition, obj.ditherNumber)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also traverse relations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Getting all NispDetectors whose frame observation id is 53877 or 54349 and \n",
    "# filterWheelPosition is Y.\n",
    "# Notice that here we also use the 'in' operator\n",
    "\n",
    "result = NispDetector.objects.filter(rawFrame__observationId__in=[53877, 54349],\n",
    "                                     rawFrame__filterWheelPosition='Y').order_by(\n",
    "                                     'rawFrame__observationId', 'rawFrame__ditherNumber', \n",
    "                                     'detectorId')\n",
    "\n",
    "for obj in result:\n",
    "    print(obj.rawFrame.observationId, obj.rawFrame.ditherNumber, obj.detectorId)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# OR we can find the NispRawFrame whose referenced file url contains \"LE1_NISP_52926-J-2\"\n",
    "\n",
    "result = NispRawFrame.objects.filter(frameFile__url__contains=\"LE1_NISP_52926-J-2\")\n",
    "\n",
    "for obj in result:\n",
    "    print(obj.observationId, obj.frameFile.url)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In order to retrive a single object, instead of using **filter** we can use the **get** method. This method returns one object and raise exceptions if no object is found or if multiple objects satisfy the query"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "obj = NispRawFrame.objects.get(observationId=53892)\n",
    "\n",
    "# now we delete such object from the database\n",
    "\n",
    "obj.delete()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Serializers\n",
    "\n",
    "Let's see some differences between the plain Django serializers and the ModelSerializer class provided by the Django REST framework.\n",
    "The first example uses the Django core serializers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from django.core import serializers\n",
    "\n",
    "data = serializers.serialize('json',NispRawFrame.objects.filter(observationId=53877, \n",
    "                            filterWheelPosition='Y').order_by('ditherNumber'))\n",
    "\n",
    "print(data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The following example, instead, uses the Django REST framework ModelSerializer class. In particular, see the file imagedb/serializers.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from imagedb.serializers import NispRawFrameSerializer\n",
    "import json\n",
    "\n",
    "frame = NispRawFrameSerializer(NispRawFrame.objects.get(id=1))\n",
    "print(json.dumps(frame.data, indent=2))\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Django Shell-Plus",
   "language": "python",
   "name": "django_extensions"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
Marco Frailis's avatar
Marco Frailis committed
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}