Commit 27a50fc7 authored by Aurélien Campéas's avatar Aurélien Campéas
Browse files

tsio: new api entry `get_history` which build a serie containing all the history

This serie has a multi-index whose first column is the insertion date.
By default we get all the serie history. We can get sub-parts by
passing values to `from_revision_date` and `to_revision_date`.


resolves #19
parent 2e4eadb6b527
......@@ -778,6 +778,91 @@ a b c
# the result ts have now 3 values for each point in 'a'
def test_get_history(engine):
tsh = TimeSerie()
for numserie in (1, 2, 3):
with engine.connect() as cn:
with tsh.newchangeset(cn, 'aurelien.campeas@pythonian.fr',
_insertion_date=datetime(2017, 2, numserie)):
tsh.insert(cn, genserie(datetime(2017, 1, 1), 'D', numserie), 'smallserie')
ts = tsh.get(engine, 'smallserie')
assert_df("""
2017-01-01 0.0
2017-01-02 1.0
2017-01-03 2.0
""", ts)
logs = tsh.log(engine, names=['smallserie'])
assert [
{'author': 'aurelien.campeas@pythonian.fr',
'date': datetime(2017, 2, 1, 0, 0),
'names': ['smallserie']
},
{'author': 'aurelien.campeas@pythonian.fr',
'date': datetime(2017, 2, 2, 0, 0),
'names': ['smallserie']
},
{'author': 'aurelien.campeas@pythonian.fr',
'date': datetime(2017, 2, 3, 0, 0),
'names': ['smallserie']
}
] == [{k: v for k, v in log.items() if k != 'rev'}
for log in logs]
histts = tsh.get_history(engine, 'smallserie')
assert_df("""
insertion_date value_date
2017-02-01 2017-01-01 0.0
2017-02-02 2017-01-01 0.0
2017-01-02 1.0
2017-02-03 2017-01-01 0.0
2017-01-02 1.0
2017-01-03 2.0
""", histts)
for idx, idate in enumerate(histts.groupby('insertion_date').groups):
with engine.connect() as cn:
with tsh.newchangeset(cn, 'aurelien.campeas@pythonian.f',
_insertion_date=idate):
tsh.insert(cn, histts[idate], 'smallserie2')
# this is perfectly round-tripable
assert (tsh.get(engine, 'smallserie2') == ts).all()
assert (tsh.get_history(engine, 'smallserie2') == histts).all()
# get history ranges
tsa = tsh.get_history(engine, 'smallserie',
from_insertion_date=datetime(2017, 2, 2))
assert_df("""
insertion_date value_date
2017-02-02 2017-01-01 0.0
2017-01-02 1.0
2017-02-03 2017-01-01 0.0
2017-01-02 1.0
2017-01-03 2.0
""", tsa)
tsb = tsh.get_history(engine, 'smallserie',
to_insertion_date=datetime(2017, 2, 2))
assert_df("""
insertion_date value_date
2017-02-01 2017-01-01 0.0
2017-02-02 2017-01-01 0.0
2017-01-02 1.0
""", tsb)
tsc = tsh.get_history(engine, 'smallserie',
from_insertion_date=datetime(2017, 2, 2),
to_insertion_date=datetime(2017, 2, 2))
assert_df("""
insertion_date value_date
2017-02-02 2017-01-01 0.0
2017-01-02 1.0
""", tsc)
def test_add_na(engine):
tsh = TimeSerie()
......
......@@ -188,6 +188,25 @@ class TimeSerie(object):
group[seriename] = serie
return group
def get_history(self, cn, name,
from_insertion_date=None,
to_insertion_date=None):
table = self._get_ts_table(cn, name)
if table is None:
return
logs = self.log(cn, names=[name],
fromdate=from_insertion_date,
todate=to_insertion_date)
series = []
for log in logs:
serie = self.get(cn, name, revision_date=log['date'])
revdate = pd.Timestamp(log['date'])
mindex = [(revdate, valuestamp) for valuestamp in serie.index]
serie.index = pd.MultiIndex.from_tuples(mindex, names=['insertion_date', 'value_date'])
series.append(serie)
return pd.concat(series)
def exists(self, cn, name):
return self._get_ts_table(cn, name) is not None
......@@ -209,7 +228,9 @@ class TimeSerie(object):
stats['serie names'] = [row for row, in cn.execute(sql).fetchall()]
return stats
def log(self, cn, limit=0, diff=False, names=None, authors=None, fromrev=None, torev=None):
def log(self, cn, limit=0, diff=False, names=None, authors=None,
fromrev=None, torev=None,
fromdate=None, todate=None):
"""Build a structure showing the history of all the series in the db,
per changeset, in chronological order.
"""
......@@ -234,6 +255,12 @@ class TimeSerie(object):
if torev:
sql = sql.where(cset.c.id <= torev)
if fromdate:
sql = sql.where(cset.c.insertion_date >= fromdate)
if todate:
sql = sql.where(cset.c.insertion_date <= todate)
sql = sql.where(cset.c.id == cset_series.c.csid
).where(cset_series.c.serie == reg.c.name)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment