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. |