Getting Started with Objectivity/Python

Introduction

Objectivity/Python is a programming interface for writing Python applications and scripts that store and manipulate persistent data in an Objectivity/DB federated database. Python is an efficient and well-supported object-oriented language that is particularly useful for rapid prototyping and for invoking administrative tasks programmatically. For full details on Python, go to the Python website.

This document assumes that:

If you are also learning the Python language for the first time, it is recommended that you run the Python language tutorial before you run the Objectivity/Python tutorial.

Uses for Objectivity/Python

Objectivity/Python can be used for administrative tasks, quality-assurance tasks, and analysis and repair tasks. The following are examples of these types of tasks.

Application-development tasks:

Administrative tasks:

Quality-assurance tasks:

Analysis and repair tasks:

Tutorial

This tutorial leads you through several simple exercises using Pythonís interactive capability.

Note: A sample script that includes the commands in this tutorial (as well as a few others) is available:

installDir/samples/python/tutorial/tutorial.py

Note: This steps in this tutorial apply for non-placement-managed federated databases.

Before You Start

Before you start this tutorial, make sure you have an Objectivity license that authorizes the use of Objectivity/Python and that you have set up a default license file for your Objectivity license. Then, perform the following steps from a command prompt:

  1. If you have not already done so, make sure the lock server is running on your computer.
    C:\myprojects>oolockserver

    If the lock server is not running, see the installation and configuration documentation on the Objectivity Developer Network.

  2. Create a new federated database. For example:
  3. C:\myprojects>oonewfd -fdfilepath tutorial.fdb -lockserver %COMPUTERNAME% tutorial.boot

As an alternative to performing the two preceding steps, you can call Objectivity/DB tools from the Python interpreter.

  1. Start the Python interpreter.
  2.  C:\myprojects>python

    The Python interpreter displays information about the Python version.

  3. Import the os module from the Standard Python Library.
  4. >>> import os
  5. Import the socket module from the Standard Python Library.
  6. >>> import socket
  7. Set a variable hostname to the name of your computer.
  8. >>> hostname = socket.gethostname()
  9. If you have not already done so, start the lock server.
  10. >>> os.system("oolockserver")
    Objectivity/DB (TM) Lock Server Utility, Version: dev 10.1 Jun  2 2010
    Copyright (c) Objectivity, Inc 1989, 2010. All rights reserved.
    
    Lock Server has been started.
  11. Create the new federated database.
  12. >>> os.system("oonewfd -fdfilepath tutorial.fdb -lockserver " + hostname + " tutorial.boot")

Starting Objectivity/Python

  1. If you have not already done so, start the Python interpreter in the same location you created the federated database. For example:
  2. C:\myprojects>python

    The Python interpreter displays information about the Python version.

  3. Import the Objectivity/Python module, oopython.
  4. >>> import oopython

    This creates an extension module through which all of Objectivity/Python's capabilities are available. You may want to examine Objectivity/Python Programmer's Reference to get a feel for all of the methods available on the oopython module, as only a few will be considered in this tutorial.

  5. Initialize Objectivity/DB resources for the process.
  6. >>> oopython.startup()
  7. Get a connection object for the tutorial federated database.
  8. >>> connection = oopython.getConnection('tutorial.boot')
  9. Create a session with an empty name.
  10. >>> session = connection.createSession('')

    As an alternative to performing the two preceding steps, you can use a one-step shortcut that creates a session with all of the default parameters.

    >>> session = oopython.createSession('tutorial.boot')

Adding Persistence-Capable Classes to the Schema

    This section shows you how to add classes to the schema. In Objectivity/DDL, the classes would look like this:

    // Objectivity/DDL class definition of Person
    class Person : public ooObj
    {
       ooVString name;
       uint8 age;
       uint8 status;
    
       ooRef(Organization) organization <-> members[]
    
       // Optional method definitions
    }
    
    // Objectivity/DDL class definition of Organization
    class Organization : public ooObj
    {
       ooVString name;
       ooRef(Person)members[] <-> organization
    }
    
  1. Start an update transaction.
  2. >>> session.begin(oopython.oocUpdate)
  3. Get the schema object from oopython.
  4. >>> schema = oopython.getSchema()
  5. Get the top module from the schema.
  6. >>> topModule = schema.getTopModule()

    In Objectivity/Python, all schema updates are performed via Objectivity/DB Active Schema. All schemas are organized into modules; every schema has a top module. Note that schema modules are distinct from the oopython module.

  7. Add the new Person class to the top module of the schema.
  8. >>> personClass = topModule.addClass('Person')
  9. Add members to the Person class and make it persistence-capable.
  10. >>> personClass.addBaseClass('ooObj')
    >>> personClass.addEmbeddedMember('name', 'ooVString')
    >>> personClass.addIntMember('age', oopython.oocUInt8)
    >>> personClass.addIntMember('status', oopython.oocUInt8)
    >>> personClass.addBiDirMember('organization', 'Organization', 'members', 1, 0)
  11. Add the Organization class to the top module of the schema.
  12. >>> orgClass = topModule.addClass('Organization')
    >>> orgClass.addBaseClass('ooObj')
    >>> orgClass.addEmbeddedMember('name', 'ooVString')
    >>> orgClass.addBiDirMember('members', 'Person', 'organization', 0, 1)
  13. Activate proposals and commit the transaction to make the new classes permanent.
  14. >>> schema.activateProposals()
    >>> session.commit()

    In general, schema updates should be performed in a separate transaction from other types of database updates.

Creating Databases and Containers

  1. Start a new transaction.
  2. >>> session.begin(oopython.oocUpdate)
  3. Create a database.
  4. >>> db = session.getFd().addDb('tutorial')
  5. Create a container within the database you just created.
  6. >>> cont = db.addContainer('tutorialData')

Viewing Information About Objects

When you enter just the name of an object, information is displayed about it. For Objectivity/DB objects (ooDBObj, ooContObj, ooObj) the oopython module displays the OID, the type of object, and, if applicable, the system name. Alternatively, you can display specific objects.

  1. View information about your database and container.
  2. >>> db
    #2-0-0-0
    (Database) tutorial
    >>> cont
    #2-3-1-1
    (Container) tutorialData
  3. Call the container's oid method to get the OID of the container.

Adding Methods to Persistence-Capable Classes

This section continues in the same transaction you started in a previous section.

After adding an application-defined, persistence-capable class to the schema as described in Adding Persistence-Capable Classes to the Schema, you can add methods to your class. To do this, you need to make your class inherit from the class Persistent. Then, create an initializer (using Python __init__) and call the makePersistent inherited method from the initializer. Your class can now be instantiated using the intializer, and its methods are available, as are any attributes that were previously defined in the schema.

  1. Create a class that inherits from Persistent and includes an initializer that accepts an argument for the container in which to create the object:
  2. >>> class Person(oopython.Persistent):
    ...    def __init__(self, container, name="", status=1):
    ...        self.persist(container)
    ...        self.name = name
    ...        self.status = status
    
    ...    def persist(self, container):
    ...        self.makePersistent(container)
    
  3. (Optional) Add other methods to the class:
  4. ...    def printTest(self):
    ...        print "\n\n*** Hello world!\n"
    ...
    

Adding Basic Objects

There are two approaches for adding persistent objects.

The storage layout (shape) for instances of a particular class are the same regardless of which approach is used for creating those instances.

The following sections continue in the same transaction you started in a previous section and shows you how to add several basic objects to containers.

Adding Basic Objects Using oopython.addObject

  1. Add a Person object to the container.
  2. >>> sam = oopython.addObject(cont, 'Person')

    The first argument to addObject is where to place the new object, and the second is the type of object to create.

  3. Set Samís data attributes.
  4. >>> sam.name = 'Sam'
    >>> sam.age = 30

    Because you added name and age attributes to the Person class, you can now use their attribute names after the '.' operator to refer to them. In this example, you placed the attribute on the left hand side of the '=' operator, which sets the attributes' values.

  5. Get the values you specified.
  6. >>> sam.age
    30
    >>> name = sam.name
    >>> name
    'Sam'
    >>> print sam.name
    Sam

    Placing the attribute on the right hand side of the '=' operator or passing it as an argument reads the value.

  7. Add a few more Person objects and set their attributes.
  8. >>> lisa = oopython.addObject(cont, 'Person')
    >>> lisa.name = 'Lisa'
    >>> lisa.age = 28
    >>> john = oopython.addObject(cont, 'Person')
    >>> john.name = 'John'
    >>> john.age = 55
  9. Add an Organization object and set the name.
  10. >>> accounting = oopython.addObject(cont, 'Organization')
    >>> accounting.name = 'Accounting'
  11. Add a few of the Person objects to the Organization objectís members relationship.
  12. >>> accounting.members.add(sam)
    >>> accounting.members.add(lisa)
  13. Add John to the Organization.
  14. >>> john.organization = accounting

    Because there is a bidirectional relationship between your classes, you can add objects to those classes bidirectionally.

Adding Basic Objects Using a Python Initializer

  1. Using the initializer created previously, create a new Person instance in the container referenced by cont.
  2. >>>> sue = Person(cont)
  3. Set some attributes.
  4. >>> sue.name = 'Sue'
    >>> sue.age = 41
    >>> sue.organization = accounting
  5. (Optionally) Call a method on the new object:
  6. >>>> sue.printTest()
    
    Hello world!
    

    Note: You can still use the oopython.addObject method to create instances of classes that have application-defined methods, but you will only have access to attributes defined in the schema, not the methods.

Reading the Data

  1. Commit all the changes before starting a read-only transaction.
  2. >>> session.commit()
  3. Start the transaction.
  4. >>> session.begin(oopython.oocRead)
  5. Iterate over all of the Organization objects in the container and print the members.
  6. >>> for org in cont.getScanObjs('Organization'):
    ...     print 'Organization:' + org.name
    ...     for member in org.members.getObjs():
    ...          print 'Member: %s Age: %s' % (member.name, member.age)
    ...
    
    Organization: Accounting
    
     Member: Sam Age: 30
    
     Member: Lisa Age: 28
    
     Member: John Age: 55
    
     Member: Sue Age: 41
  7. Commit the session.
  8. >>> session.commit()

Getting Information About Objectivity/Python Classes

  1. Use the Python dir function on an object of a specified class, in this case the connection class, to discover the methods associated with that class.
  2. >>> dir(connection)
    ['bootfile','createSession','createSessionPool','getSessionFromPool','returnSessionToPool']
  3. Print the documentation to learn the signature and description of each method, for example, the bootfile method of the connection class.
  4. >>> print connection.bootfile.__doc__
    bootfile()
    -- Return Type: string
    -- Returns the boot file of the FD/AP that this connection is connected to.

    For more information about Objectivity/Python class members, see the Objectivity/Python Programmer's Reference documentation, which is distributed with the Objectivity/Python product.

Shutting Down Objectivity/Python

  1. Shut down the oopython module to make sure resources are released.
  2. >>> oopython.shutdown()