Skip to content

Commit 36ca462

Browse files
authored
Merge pull request #18 from CloverHealth/new-style-temporal
simple usage doc
2 parents e8c2118 + c12d380 commit 36ca462

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed

docs/README.md

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# Temporal SQLAlchemy
2+
3+
## Usage
4+
5+
I'll start with the caveats, as there are a few:
6+
7+
* you cannot track the history of properties with `onupdate`, `server_default`
8+
or `server_onupdate`
9+
10+
```python
11+
import sqlalchemy as sa
12+
import temporal_sqlalchemy as temporal
13+
14+
15+
class MyModel(temporal.TemporalModel, SomeBase):
16+
id = sa.Column(sa.BigInteger, primary_key=True)
17+
# this will throw an error
18+
prop_a = sa.Column(sa.Text, onupdate='Some Update Value')
19+
# this will also throw an error
20+
prop_b = sa.Column(sa.Text, server_default='Some Server Default')
21+
```
22+
23+
* you have to "temporalize" your session
24+
25+
```python
26+
import sqlalchemy.orm as orm
27+
import temporal_sqlalchemy as temporal
28+
29+
sessionmaker = orm.sessionmaker()
30+
session = sessionmaker()
31+
temporal.temporal_session(session)
32+
33+
foo = MyModel(prop_a='first value', prop_b='also first first value')
34+
session.add(foo)
35+
session.commit()
36+
37+
38+
with foo.clock_tick():
39+
foo.prop_a = 'new value'
40+
foo.prop_b = 'also new value'
41+
42+
session.commit()
43+
```
44+
45+
* default values are tricky. If you need to record the state of a default
46+
value, or need `None` to have historical meaning you must be deliberate.
47+
Additionally, we cannot currently handle callable defaults that take a
48+
context
49+
[described here](http://docs.sqlalchemy.org/en/rel_1_0/core/defaults.html#context-sensitive-default-functions)
50+
51+
```python
52+
import sqlalchemy as sa
53+
import sqlalchemy.orm as orm
54+
import temporal_sqlalchemy as temporal
55+
56+
sessionmaker = orm.sessionmaker()
57+
session = sessionmaker()
58+
temporal.temporal_session(session)
59+
60+
61+
class MyModel(temporal.TemporalModel, SomeBase):
62+
__tablename__ = 'my_model_table'
63+
__table_args__ = {'schema': 'my_schema'}
64+
65+
id = sa.Column(sa.BigInteger, primary_key=True)
66+
description = sa.Column(sa.Text)
67+
68+
class Temporal:
69+
track = ('description', )
70+
71+
72+
m = MyModel()
73+
session.add(m)
74+
session.commit()
75+
76+
assert m.vclock == 1
77+
assert m.description == None
78+
79+
description_hm = temporal.get_history_model(MyModel.description)
80+
81+
history = session.query(description_hm).filter(description_hm.entity==m)
82+
83+
# no history entry is created!
84+
assert history.count() == 0
85+
86+
# do this instead
87+
m2 = MyModel(description=None)
88+
session.add(m2)
89+
session.commit()
90+
91+
assert m2.vclock == 1
92+
assert m2.description == None
93+
94+
history = session.query(description_hm).filter(description_hm.entity==m2)
95+
96+
# history entry is now created
97+
assert history.count() == 1
98+
```
99+
100+
### Using Your Model
101+
102+
103+
```python
104+
import sqlalchemy.orm as orm
105+
import temporal_sqlalchemy as temporal
106+
107+
sessionmaker = orm.sessionmaker()
108+
session = sessionmaker()
109+
110+
temporal.temporal_session(session)
111+
instance = MyModel(description="first description")
112+
113+
assert instance.vclock == 1
114+
115+
session.add(instance)
116+
session.commit()
117+
```
118+
119+
### Updating your instance
120+
121+
```python
122+
123+
with instance.clock_tick():
124+
instance.description = "second description"
125+
126+
assert instance.vclock = 2
127+
session.commit()
128+
129+
```
130+
131+
### inspecting history
132+
133+
```python
134+
import temporal_sqlalchemy as temporal
135+
136+
description_hm = temporal.get_history_model(MyModel.description)
137+
138+
history = session.query(description_hm).filter(description_hm.entity==instance)
139+
140+
assert history.count() == 2
141+
assert history[0].description == 'first description'
142+
assert history[1].description == 'second description'
143+
```

0 commit comments

Comments
 (0)