root / elixir / trunk / tests / test_autoload.py @ 93

Revision 93, 5.5 kB (checked in by ged, 6 years ago)

- (Hopefully) fixed reflecting has_and_belongs_to_many relationships.

Now, you have to specify at least one of either the local_side or remote_side
argument.

- Changed the approach to reflecting/autoloading belongs_to relationships.

This shouldn't change anything to how it's used but allowed me to factor
some code with has_and_belongs_to_many relationships.

- Fixed wrong field length is autoload test (it is not noticeable with sqlite).
- Use an explicit metaclass for entities, so that people can define their own

base class.

Line 
1"""
2    simple test case
3"""
4
5import sqlalchemy
6from sqlalchemy import Table, Column, ForeignKey, BoundMetaData
7from sqlalchemy.types import *
8from elixir import *
9from elixir import metadata, objectstore
10import elixir
11import datetime
12
13# First create the tables (it would be better to use an external db)
14engine = sqlalchemy.create_engine('sqlite:///')
15meta = BoundMetaData(engine)
16
17person_table = Table('person', meta,
18    Column('id', Integer, primary_key=True),
19    Column('father_id', Integer, ForeignKey('person.id')),
20    Column('name', Unicode(32)))
21person_table.create()
22
23animal_table = Table('animal', meta,
24    Column('id', Integer, primary_key=True),
25    Column('name', String(30)),
26    Column('color', String(15)),
27    Column('owner_id', Integer, ForeignKey('person.id')),
28    Column('feeder_id', Integer, ForeignKey('person.id')))
29animal_table.create()
30
31category_table = Table('category', meta,
32    Column('name', String, primary_key=True))
33category_table.create()
34
35person_category_table = Table('person_category', meta,
36    Column('person_id', Integer, ForeignKey('person.id')),
37    Column('category_name', String, ForeignKey('category.name')))
38person_category_table.create()
39
40person_person_table = Table('person_person', meta,
41    Column('person_id1', Integer, ForeignKey('person.id')),
42    Column('person_id2', Integer, ForeignKey('person.id')))
43person_person_table.create()
44
45elixir.delay_setup = True
46elixir.options_defaults.update(dict(autoload=True, shortnames=True))
47
48class Person(Entity):
49    belongs_to('father', of_kind='Person')
50    has_many('children', of_kind='Person')
51    has_many('pets', of_kind='Animal', inverse='owner')
52    has_many('animals', of_kind='Animal', inverse='feeder')
53    has_and_belongs_to_many('categories', of_kind='Category', 
54                            tablename='person_category')
55    has_and_belongs_to_many('appreciate', of_kind='Person',
56                            tablename='person_person',
57                            local_side='person_id1')
58    has_and_belongs_to_many('isappreciatedby', of_kind='Person',
59                            tablename='person_person',
60                            local_side='person_id2')
61
62    def __str__(self):
63        s = '%s\n' % self.name.encode('utf-8') 
64        for pet in self.pets:
65            s += '  * pet: %s\n' % pet.name
66        return s
67
68
69class Animal(Entity):
70    belongs_to('owner', of_kind='Person', colname='owner_id')
71    belongs_to('feeder', of_kind='Person', colname='feeder_id')
72
73
74class Category(Entity):
75    has_and_belongs_to_many('persons', of_kind='Person', 
76                            tablename='person_category')
77
78elixir.delay_setup = False
79elixir.options_defaults.update(dict(autoload=False, shortnames=False))
80
81#-----------
82
83class TestAutoload(object):
84    def setup(self):
85        metadata.connect(engine)
86        setup_all()
87   
88    def teardown(self):
89        drop_all()
90   
91    def test_autoload(self):
92        snowball = Animal(name="Snowball II", color="grey")
93        slh = Animal(name="Santa's Little Helper")
94        homer = Person(name="Homer", animals=[snowball, slh], pets=[slh])
95        lisa = Person(name="Lisa", pets=[snowball])
96       
97        objectstore.flush()
98        objectstore.clear()
99       
100        homer = Person.get_by(name="Homer")
101        lisa = Person.get_by(name="Lisa")
102       
103        print homer
104
105        assert len(homer.animals) == 2
106        assert homer == lisa.pets[0].feeder
107        assert homer == slh.owner
108
109    def test_autoload_selfref(self):
110        grampa = Person(name="Abe")
111        homer = Person(name="Homer")
112        bart = Person(name="Bart")
113        lisa = Person(name="Lisa")
114       
115        grampa.children.append(homer)
116        homer.children.append(bart)
117        lisa.father = homer
118       
119        objectstore.flush()
120        objectstore.clear()
121       
122        p = Person.get_by(name="Homer")
123       
124        print "%s is %s's child." % (p.name, p.father.name)
125        print "His children are: %s." % (
126                " and ".join(c.name for c in p.children))
127       
128        assert p in p.father.children
129        assert p.father is Person.get_by(name="Abe")
130        assert p is Person.get_by(name="Lisa").father
131
132    def test_autoload_has_and_belongs_to_many(self):
133        stupid = Category(name="Stupid")
134        simpson = Category(name="Simpson")
135        old = Category(name="Old")
136
137        grampa = Person(name="Abe", categories=[simpson, old])
138        homer = Person(name="Homer", categories=[simpson, stupid])
139        bart = Person(name="Bart")
140        lisa = Person(name="Lisa")
141       
142        simpson.persons.extend([bart, lisa])
143       
144        objectstore.flush()
145        objectstore.clear()
146       
147        c = Category.get_by(name="Simpson")
148        grampa = Person.get_by(name="Abe")
149       
150        print "Persons in the '%s' category: %s." % (
151                c.name, 
152                ", ".join(p.name for p in c.persons))
153       
154        assert len(c.persons) == 4
155        assert c in grampa.categories
156
157    def test_autoload_has_and_belongs_to_many_selfref(self):
158        barney = Person(name="Barney")
159        homer = Person(name="Homer", appreciate=[barney])
160
161        objectstore.flush()
162        objectstore.clear()
163       
164        homer = Person.get_by(name="Homer")
165        barney = Person.get_by(name="Barney")
166
167        assert barney in homer.appreciate
168        assert homer in barney.isappreciatedby
169
170if __name__ == '__main__':
171    test = TestAutoload()
172    test.setup()
173    test.test_autoload_has_and_belongs_to_many_selfref()
174#    test.test_autoload()
175    test.teardown()
Note: See TracBrowser for help on using the browser.