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:secretpw@localhost: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" <
gdemen...@gmail.com> wrote:
> On Sun, Apr 20, 2008 at 8:49 PM, DanL <
dlop...@mit.edu> 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...