You're right... what I posted completely does not work.  I apologize
for that... it was a combination of it being really late and me not
keeping track of what hackish additions did make it work and which
didn't.  Anyways, I would like to figure this out, and I need you
guys' help.


Lets step back from Turbogears for a second and go to the most simple
possible multi-file model with a dependency between models.  I'll be
using the Man/Dog classes I wrote up in that wiki.  Lets start with
putting everything into one file: the model.py file.  A second file
(script_create_tables.py) creates the metadata and calls
create_tables.  So our two-file project looks like this:


== script_create_tables.py ==
=============================

from elixir                 import metadata, create_all
metadata.bind = "mysql://multimodel:[EMAIL PROTECTED]:3306/
multifilemodel"
metadata.bind.echo = True


from model import *


create_all()
=============================


== model.py                ==
=============================
from elixir import Entity, setup_all

from elixir import Field, Unicode, ManyToOne, OneToMany

class Dog(Entity):
    name = Field(Unicode(10))
    owner = ManyToOne('Man')
    def __repr__(self):
        return '<Dog \'%s\'>' % (self.name)

class Man(Entity):
    name = Field(Unicode(10))
    pets = OneToMany('Dog')
    def __repr__(self):
        return '<Man \'%s\'>' % (self.name)



## Debugging Outputs
print "Man's metaclass's entities: "
print Man.__metaclass__._entities


## Setup the Tables
setup_all()
=============================

This works great.



Now, lets say we want to move just Man into a separate file,
humans.py:

== new model.py            ==
=============================
from elixir import Entity, setup_all

from elixir import Field, Unicode, ManyToOne, OneToMany

class Dog(Entity):
    name = Field(Unicode(10))
    owner = ManyToOne('Man')
    def __repr__(self):
        return '<Dog \'%s\'>' % (self.name)

from humans import *


## Debugging Outputs
print "Man's metaclass' entities: "
print Man.__metaclass__._entities


## Setup the Tables
setup_all()
=============================


== new humans.py           ==
=============================
from elixir import Entity, Field, Unicode, OneToMany

class Man(Entity):
    name = Field(Unicode(10))
    pets = OneToMany('Dog')
    def __repr__(self):
        return '<Man \'%s\'>' % (self.name)
=============================


Now we get an error tracing up to setup_all().  The error is:
  KeyError: 'Dog'

(Note: in my testing these three files, humans.py actually resides in
a module called "submodels".  This is to reflect the ultimate goal of
putting this in the scope of a Turbogears project, but the results
appear to be the same as above)


Now comes where I need the community's help.  I believe the problem
lies in the construction of the Elixir MetaEntity metaclass object.  I
don't know exactly how the Elixir MetaEntity is constructed, but I can
guess its function.  I need someone who understands the MetaEntity to
help me figure this out:

In the first case (all Entities in model.py, things worked), the
printout of the metaclass's entities was:

{24620536: {'Man': <class 'tgmultifilemodel.model.Man'>,
            'Dog': <class 'tgmultifilemodel.model.Dog'>,
            'Entity': <class 'elixir.entity.Entity'>}}

This is what works (and what we want to get).  In the second case (Man-
class moved to humans.py, KeyError), the printout of the metaclass's
entites was:
{24630320: {'Entity': <class 'elixir.entity.Entity'>,
            'Man': <class 'tgmultifilemodel.submodels.humans.Man'>},
 24633600: {'Man': <class 'tgmultifilemodel.submodels.humans.Man'>,
            'Dog': <class 'tgmultifilemodel.model.Dog'>,
            'Entity': <class 'elixir.entity.Entity'>}}

This explains the KeyError: 'Dog': in the 24630320 domain/set/whatever-
it-is, the Dog entity is not listed, and so when we try to setup_all
that set, we understandably get the KeyError because of Man's
reference to (the missing) Dog class.

Here's where my understanding of Elixir ends and I hope someone can
fill in the blanks.  How is this metaentity class constructed?  Why
the different sets when we split across multiple files?  And the
million-dollar question: how can we split dependant entities across
multiple files and make elixir's metaentity not create that pesky
partially-filled domain that breaks stuff?


On Apr 21, 6:11 am, "Gaetan de Menten" <[EMAIL PROTECTED]> wrote:
> On Sun, Apr 20, 2008 at 8:49 PM, DanL <[EMAIL PROTECTED]> wrote:
>
> >  Hey guys,
>
> >  I've been working on a large Turbogears project that required me to
> >  split an Elixir model across multiple files.  As a programmer new to
> >  Python and Elixir, I had some troubles (a good tutorial for this has
> >  noticeably missing from the docs).
>
> >  There were a few subtle (and frustrating) tricks involved, so I wrote
> >  up in the wiki the technique and patterns I ultimately used, along
> >  with some common pitfalls I encountered.  It is written with a
> >  Turbogears project in mind, but it should be abstract enough that it
> >  will apply to Pylons projects as well.
>
> >  Check it out under 
> > Recipes:http://elixir.ematia.de/trac/wiki/Recipes/SplittingAModelAcrossMultip...
>
> Thanks *a lot* for this. I've been wanting to add an entry in the FAQ
> for this for quite a while but didn't find (or take) the time yet.
>
>
>
> >  Please comment or fix if I did anything architecturally wrong or bad
> >  -- my background is mostly in C++, so I may not be grasping certain
> >  Python concepts properly.
>
> There are a few mistakes and oddities. Some of which rather important
> (I fail to see how it works at all the way you do it) but I have to
> investigate it further to correct and comment properly what's wrong.
>
> The most minor one is that in the following line:
> using_options(shortnames=True, tablename="my_man_table")
>
> the shortnames=True is totally useless as it's an option which is only
> used when you don't specify the table name manually.
>
> Thanks again,
> --
> Gaƫtan de Mentenhttp://openhex.org
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"SQLElixir" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlelixir?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to