File: attributes.py

package info (click to toggle)
sqlalchemy 0.6.3-3%2Bsqueeze1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 10,744 kB
  • ctags: 15,132
  • sloc: python: 93,431; ansic: 787; makefile: 137; xml: 17
file content (124 lines) | stat: -rw-r--r-- 3,363 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

import new

class MethodDescriptor(object):
    def __init__(self, func):
        self.func = func
    def __get__(self, instance, owner):
        if instance is None:
            return new.instancemethod(self.func, owner, owner.__class__)
        else:
            return new.instancemethod(self.func, instance, owner)

class PropertyDescriptor(object):
    def __init__(self, fget, fset, fdel):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel
    def __get__(self, instance, owner):
        if instance is None:
            return self.fget(owner)
        else:
            return self.fget(instance)
    def __set__(self, instance, value):
        self.fset(instance, value)
    def __delete__(self, instance):
        self.fdel(instance)
        
def hybrid(func):
    return MethodDescriptor(func)

def hybrid_property(fget, fset=None, fdel=None):
    return PropertyDescriptor(fget, fset, fdel)

### Example code

from sqlalchemy import MetaData, Table, Column, Integer
from sqlalchemy.orm import mapper, create_session

metadata = MetaData('sqlite://')
metadata.bind.echo = True

print "Set up database metadata"

interval_table1 = Table('interval1', metadata,
    Column('id', Integer, primary_key=True),
    Column('start', Integer, nullable=False),
    Column('end', Integer, nullable=False))

interval_table2 = Table('interval2', metadata,
    Column('id', Integer, primary_key=True),
    Column('start', Integer, nullable=False),
    Column('length', Integer, nullable=False))

metadata.create_all()

# A base class for intervals

class BaseInterval(object):
    @hybrid
    def contains(self,point):
        return (self.start <= point) & (point < self.end)
    
    @hybrid
    def intersects(self, other):
        return (self.start < other.end) & (self.end > other.start)

    def __repr__(self):
        return "%s(%s..%s)" % (self.__class__.__name__, self.start, self.end)

# Interval stored as endpoints

class Interval1(BaseInterval):
    def __init__(self, start, end):
        self.start = start
        self.end = end
    
    length = hybrid_property(lambda s: s.end - s.start)

mapper(Interval1, interval_table1)

# Interval stored as start and length

class Interval2(BaseInterval):
    def __init__(self, start, length):
        self.start = start
        self.length = length
    
    end = hybrid_property(lambda s: s.start + s.length)

mapper(Interval2, interval_table2)

print "Create the data"

session = create_session()

intervals = [Interval1(1,4), Interval1(3,15), Interval1(11,16)]

for interval in intervals:
    session.add(interval)
    session.add(Interval2(interval.start, interval.length))

session.flush()

print "Clear the cache and do some queries"

session.expunge_all()

for Interval in (Interval1, Interval2):
    print "Querying using interval class %s" % Interval.__name__
    
    print
    print '-- length less than 10'
    print [(i, i.length) for i in session.query(Interval).filter(Interval.length < 10).all()]
    
    print
    print '-- contains 12'
    print session.query(Interval).filter(Interval.contains(12)).all()
    
    print
    print '-- intersects 2..10'
    other = Interval1(2,10)
    result = session.query(Interval).filter(Interval.intersects(other)).order_by(Interval.length).all()
    print [(interval, interval.intersects(other)) for interval in result]