Tags
http://modeling.sourceforge.net/main.html

The Modeling framework intends to fill the gap between the python object world and relational databases. It relies on a model, based on Entity-Relationship Modelling, that describes how the two worlds map to each other. From your design of such a model, the database's schema and corresponding python classes are automatically generated. Thus, once you have designed how your classes should be stored in the RDBMS, you can focus on the real challenges - the logic of your business objects - while remaining in the object-oriented world of those objects and never having to worry about the SQL and RDBMS persistence layer below.

Below you can find a quicj overview taken from their web site.

A very quick overview

Design your model
Write sample_pymodel.py:

#! /usr/bin/env python

from Modeling.PyModel import *

# Defaults
AString.defaults['width'] = 40

Entity.defaults['properties'] = [
  APrimaryKey('id', isClassProperty=0, isRequired=1, doc='PK')

]
##
_connDict = {'database': 'SampleDB', 'host': 'localhost',
             'user': 'postgres', 'password': ''}

model = Model('Sample',adaptorName='Postgresql', connDict=_connDict)

model.version='0.1'
model.entities = [
  Entity('Person',
         properties=[ AString('firstName'),
                      AString('lastName',isRequired=1)]  ),
  Entity('Address',
         properties=[  AString('street'),
                       AString('zipCode', width=10),
                       AString('town', isRequired=1) ],  ),
  ]

#---
model.associations=[
  Association('Address','Person',
              relations=['person','addresses'],
              delete=['nullify','deny'] ),
  ]

Verify the correctness of your model
shell> mdl_validate_model.py sample_pymodel.py

(note: use option -h on python scripts for details)

Generate the python code
shell> mdl_generate_python_code.py sample_pymodel.py

Note: python modules and classes can also be generated dynamically on the fly.
If you're interested in such a feature, you want to have a look at this patch https://sourceforge.net/tracker/index.php?func=detail&aid=814055&group_id=58935&atid=489337

Generate the corresponding database schema

Either get the coresponding sql statements:
shell>  mdl_generate_DB_schema.py -c -C sample_pymodel.py

CREATE TABLE PERSON (
  FIRST_NAME VARCHAR(40) , 
  LAST_NAME VARCHAR(40) NOT NULL, 
  ID INTEGER NOT NULL);

CREATE TABLE ADDRESS (
  TOWN VARCHAR(40) NOT NULL, 
  FK_PERSON INTEGER , 
  STREET VARCHAR(40) , 
  ID INTEGER NOT NULL, 
  ZIP_CODE VARCHAR(10) );

ALTER TABLE PERSON ADD PRIMARY KEY (ID);
ALTER TABLE ADDRESS ADD PRIMARY KEY (ID);

ALTER TABLE ADDRESS ADD
CONSTRAINT person FOREIGN KEY (FK_PERSON) REFERENCES PERSON(ID) 
INITIALLY DEFERRED;

CREATE SEQUENCE PK_SEQ_PERSON START 1;
CREATE SEQUENCE PK_SEQ_ADDRESS START 1;

Or create the database directly:

shell> mdl_generate_DB_schema.py -C 
--admin-dsn="localhost:template1:postgres:" sample_pymodel.py

Use it!
>>> from Sample.Person import Person
>>> from Sample.Address import Address

>>> from Modeling.EditingContext import EditingContext
>>> ec=EditingContext()

>>> # create objects
... john=Person(firstName='John', lastName='Cleese')

>>> ec.insert(john)
>>> jeanne=Person(firstName='Jeanne', lastName='Cleese')

>>> ec.insert(jeanne)

>>> # create relationships
... a_john=Address(town='London')

>>> ec.insert(a_john)
>>> john.addToAddresses(a_john); a_john.setPerson(john)

>>>
>>> a_jeanne=Address(town='Paris')
>>> ec.insert(a_jeanne)

>>> jeanne.addToAddresses(a_jeanne); a_jeanne.setPerson(jeanne)

>>> # save changes
>>> ec.saveChanges()

>>> # fetch objects
... in_london=ec.fetch('Person', 'addresses.town ilike "*london*"')

>>> [(p.getLastName(), p.getFirstName()) for p in in_london]

Another example I used for test is XML model, see XML ModelFile. Using modeling tools the schema and base classes, e.g. Book, were created. Here is Book class:
# Generated by mdl_generate_python_code.py / 2006/05/03 10:31
from Modeling.CustomObject import CustomObject
from Modeling.Validation import ValidationException
from mx.DateTime import DateTimeFrom


class Book(CustomObject):
  """
  Books are objects ...
  """

  __implements__ = CustomObject.__implements__

  def __init__(self, **kw):
    "Initializer"
    # Note: if you modify this method, it is a strong requirement that
    # every parameter gets a default value, since the framework needs to be
    # able to instanciate an object with no parameter at all.
    self._id = 0 # Primary Key: read-only!
    self._price = None
    self._title = None
    self._author=None
    for k,v in kw.items():
      self.takeValueForKey(v, k)

  def entityName(self):
      "Used by the framework to link this object to its entity"
      return "Book" # do not change


  # Attribute: id
  # This attribute is a primary key: it is a READ-ONLY attribute that should
  # not be changed
  def getId(self):
    "Return the Book / id attribute value"
    self.willRead()
    return self._id
  def validateId(self, value):
    "Edit this to enforce custom business logic"
    if 0: # your custom bizlogic
      raise ValidationException
    return

  # Attribute: price
  def getPrice(self):
    "Return the Book / price attribute value"
    self.willRead()
    return self._price

  def setPrice(self, price):
    "Change the Book / price attribute value"
    self.willChange()
    self._price  = price
  def validatePrice(self, value):
    "Edit this to enforce custom business logic"
    if 0: # your custom bizlogic
      raise ValidationException
    return

  # Attribute: title
  def getTitle(self):
    "Return the Book / title attribute value"
    self.willRead()
    return self._title

  def setTitle(self, title):
    "Change the Book / title attribute value"
    self.willChange()
    self._title  = title
  def validateTitle(self, value):
    "Edit this to enforce custom business logic"
    if 0: # your custom bizlogic
      raise ValidationException
    return
  # Relationship: author

  def getAuthor(self):
    "Return the author relationship (toOne)"
    self.willRead()
    return self._author

  def setAuthor(self, object):
    "Set the author relationship (toOne)"
    self.willChange()
    self._author=object

-- ValentinKuznetsov - 05 May 2006
Topic revision: r1 - 05 May 2006, ValentinKuznetsov
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding CLASSE Wiki? Send feedback