Re: [Modeling-users] Pythonic, and non-XML, Model description
Status: Abandoned
Brought to you by:
sbigaret
|
From: Sebastien B. <sbi...@us...> - 2003-05-16 13:52:16
|
Mario Ruggier <ma...@ru...> wrote:
[...]
> >
> > I expose here the points that were raised when trying it:
> >
> > - model & entity declarations: nothing has changed, except that I added
> > the possibility to declare 'associations' in an entity (see below)
>=20
> Like the idea a lot. It is better than using relationships because it
> encapsulates the info about both ends in one place.
> Can it replace Relationships (in client models) entirely?
Well, if we want to make this possible we need to find a way to declare
directional associations, i.e. when only E1-->E2 is neede (and not the
inverse).=20
Another thing I must stress is that Association currently associates
E1 --> E2, w/ E1:toOne-->E2 and E2:toMany-->E1
So:
- either we keep this as-is (this allows Association('Employee', 'Store'))
- or we drop the constraint (toOne e1->e2) but in that case the
multiplicity parameter is mandatory for both
> > - defaults:
> >
> > i. the way calculated defaults are declared needed to be
> > changed, example:
> >
> > model.defaults=3D{ 'packageName': MP(identity, 'name'), }
> >
> > where MP is a special class for this (MP: Method/Parameters)
> > identity is the method to be called (here identity=3Dlambda =
x:x)
> > 'name' is the name of the object's (model's) attribute to p=
ass
> > as an attribute (it should be an object's attribute)
> >
> > When multiple parameters are needed:
> > MP(function,'param1','param2')
>=20
> OK for me. My only question is that (frequently used) functions to be
> passed to MP should be included in MP, or close by, as helper
> functions,
They can be loaded within the PyModel namespace (since we import *), no
problem.
> > - relationships: there are two different ways to declare them:
> >
> > a. fully qualified rels i.e. when source and destination key are
> > specified such as in:
> >
> > Entity('Employee',
> > AForeignKey('fkStore'),
> > properties=3D[RToOne('toStore','Store',src=3D'fkStore',ds=
t=3D'id')]
> > )
> >
> > b. unqualified rels, such as in:
> >
> > Entity('Employee', properties=3D[ RToOne('toStore', 'Store') ] )
> >
> > When using such a scheme, you need to identify the inverse
> > relationship, if any, by the keyword 'inverse'; it can be specifi=
ed
> > in either relationships, or in both. Example:
> >
> > Entity('Employee', properties=3D[ RToOne('toStore', 'Store',
> > inverse=3D'toEmployees') =
] )
> >
> > Both a. and b. are implemented.
> > In case b. the foreign key is created in the source (resp.
> > destination) entity for a RToOne (resp. RToMany) relationship
>=20
> I suggest there should be (at least as recommendation) only one way.
> I would prefer (b), as it is more expressive. But, as mentioned above,
> this may all be pushed further down, and client model code should
> only deal with Associations?
Okay, now I know why I do not want to remove the RToOne/RToMany classes:
we earlier decided that one of the pre-requisite is that the PyModel
should be able to express *anything* that can be expressed in a
xml-model (and in Modeling.Model,Entity, etc.)
--> only dealing w/ associations makes it almost impossible to
explicitely declare a ForeignKey with parameters !=3D from the
defaults (or the Association's parameters set becomes to be really
complicated)
> > - new object: Association
> >
> > Association objects make it easier to quickly design a relationship
> > and its inverse. Proposed usage:
> >
> > model.entities =3D [
> > Entity('Employee'),
> > Entity('SalesClerk', parent=3D'Employee'),
> > Entity('Mark'),
> > Entity('Store'),
> > ]
> > model.associations =3D [
> > Association('Employee', 'Store'),
> > Association('Mark', 'Employee'),
> > ]
> >
> > (this is the StoreEmployee test model without the attributes)
>=20
> This is nice. Compact and expressive.
> Have you already mapped (in full, taking out relationships) the
> StoreEmp model to using Associations?
Not yet, but a basic implementation for associations is exposed in the
dev-brch PyModel.py. I was waiting for ideas on the init API before
going any further.
> > Another full usage could be:
> >
> > # [...]
> > model.associations =3D [
> > Association('Employee: toStore', 'Store: toEmployees',
> > [0,1], # Employee -----> Store
> > [0,None], # Store ---->> Employee
> > )
> > ]
> >
> > (Implementation note: for the moment Association('E1', 'E2')
> > builds a toOne E1--->E2 and a toMany E2--->E1)
> >
> > =3D> this is where I'm not clear at all. It seems to me that we should
> > be able to specify:
> > - the source and destination entity (mandatory)
> > - the multiplicity for both relationships (optional)
> > - the names of the toOne rel. and of the toMany rel. (optional)
> > - maybe extra parameters for each rels, something like:
> >
> > model.associations =3D [
> > Association('Employee: toStore', 'Store: toEmployees',
> > [0,1], # Employee -----> Store
> > [0,None], # Store ---->> Employee
> > { 'doc': 'toOne: Employee to Store' }, # Emp.to=
Store
> > { 'doc': 'toMany: Store to Employee' }, # Store.=
toEmp.
> > )
> > ]
> >
> > I'm not sure this looks pretty, so if you have ideas they are
> > welcome ;)
>=20
> One point I would like to stress is that there should be no bizarre
> variations between how a parameter is specified in one
> object or another. Thus Associations should try to follow as much
> as possible the same semantics as the others -- which is that
> required parameters are not named, and al other optional parameters
> are named and have defaults. Introducing a dictionary param will
> break that consistency... Anyway, how about:
>=20
> Association('E1','E2',
> rel =3D ['toE2', 'toE1' ]
> multiplicity=3D [ [0,1], [0,None] ],
> doc =3D ['to one', 'to many' ],
> ...
> )
>=20
> Defaults will be handled identically to other classes.
Fine, it sounds consistent. Let's summarize this (w/ the defaults):
Association('E1', 'E2',
multiplicity =3D [ [0,1], [0,None] ], # optional or mandatory?
relations =3D [ 'toE2', 'toE1s' ], # optional=20
keys =3D [ 'fkE2', 'id' ], # optional
delete =3D [ 'nullify', 'nullify' ], # optional
isClassProperty =3D [ 0, 0 ], # optional
joinSemantic =3D [ 0, 0 ], # optional
displayLabel =3D [ '', '' ], # optional
doc=3D ['to one', 'to many' ], # optional
)
> > Enclosed is a (working) version of sample_PyModel_5.py
>=20
> Nice. Version with Associations and no Relationships?
> Also, it may be a good idea to include the new way how to
> handle conndict info, even in these examples.
The new way of handling the connection dictionary (RFE #726839) only
relies on a environment variable (MDL_DB_CONNECTIONS_CFG) being set
and pointing to a specific file --> no python code needed. But we can
include a comment in the code to indicate that.
> Plus, see minor comment below.
[...]
> > Entity('Mark',
> > properties=3D[ AInteger('month', isRequired=3D1),
> > AInteger('mark', isRequired=3D1),
> > AForeignKey('toExecutive', isClassProperty=3D0),
>=20
> *** given your changes, is this needed (AForeignKey toExecutive) ?
[...]
Ok, let me clarify this. For RTone/RToMany:
- if relations specify src & dst keys, these keys *must* be
explicitly defined (for the moment being I mean, this is not an
implementation issue)
=20=20=20=20
- if not, they are automatically declared.
In the sample code, entities get a PK by default, hence only FK needs
to be declared explicitly, when applicable.
-- S=E9bastien.
|