537 lines
22 KiB
Python
537 lines
22 KiB
Python
# ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
# ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
# ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
# ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
# ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
# ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
# ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
# ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
# ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
# ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
# ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
|
|
import numpy as np
|
|
import pyarrow as pa
|
|
import pandas as pd
|
|
from datetime import date, datetime
|
|
from pytest import mark
|
|
import perspective as psp
|
|
|
|
client = psp.Server().new_local_client()
|
|
Table = client.table
|
|
|
|
|
|
class TestUpdate(object):
|
|
@mark.skip(reason="Fix for null values update yet to be implemented")
|
|
def test_update_with_missing_or_null_values(self):
|
|
tbl = Table([{"a": "1", "b": "2"}, {"a": "3", "b": "4"}], index="a")
|
|
tbl.update([{"a": "1", "b": None}])
|
|
assert tbl.view().to_records() == [{"a": "1", "b": None}, {"a": "3", "b": "4"}]
|
|
|
|
data = pd.DataFrame({"a": ["1"], "b": [None]})
|
|
|
|
arrow_table = pa.Table.from_pandas(data, preserve_index=False)
|
|
|
|
tbl.update(arrow_table)
|
|
assert tbl.size() == 2
|
|
assert tbl.view().to_records() == [{"a": "1", "b": ""}, {"a": "3", "b": "4"}]
|
|
|
|
def test_update_from_schema(self):
|
|
tbl = Table({"a": "string", "b": "integer"})
|
|
tbl.update([{"a": "abc", "b": 123}])
|
|
assert tbl.view().to_records() == [{"a": "abc", "b": 123}]
|
|
|
|
def test_update_columnar_from_schema(self):
|
|
tbl = Table({"a": "string", "b": "integer"})
|
|
tbl.update({"a": ["abc"], "b": [123]})
|
|
assert tbl.view().to_records() == [{"a": "abc", "b": 123}]
|
|
|
|
def test_update_csv(self):
|
|
tbl = Table({"a": "string", "b": "integer"})
|
|
|
|
view = tbl.view()
|
|
tbl.update("a,b\nxyz,123\ndef,100000000")
|
|
|
|
assert view.to_columns() == {"a": ["xyz", "def"], "b": [123, 100000000]}
|
|
|
|
def test_update_csv_indexed(self):
|
|
tbl = Table({"a": "string", "b": "float"}, index="a")
|
|
|
|
view = tbl.view()
|
|
tbl.update("a,b\nxyz,1.23456718\ndef,100000000.1")
|
|
|
|
assert view.to_columns() == {
|
|
"a": ["def", "xyz"],
|
|
"b": [100000000.1, 1.23456718],
|
|
}
|
|
|
|
tbl.update("a,b\nxyz,0.00000001\ndef,1234.5678\nefg,100.2")
|
|
|
|
assert view.to_columns() == {
|
|
"a": ["def", "efg", "xyz"],
|
|
"b": [1234.5678, 100.2, 0.00000001],
|
|
}
|
|
|
|
def test_update_append(self):
|
|
tbl = Table([{"a": "abc", "b": 123}])
|
|
tbl.update([{"a": "def", "b": 456}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": "abc", "b": 123},
|
|
{"a": "def", "b": 456},
|
|
]
|
|
|
|
def test_update_partial(self):
|
|
tbl = Table([{"a": "abc", "b": 123}], index="a")
|
|
tbl.update([{"a": "abc", "b": 456}])
|
|
assert tbl.view().to_records() == [{"a": "abc", "b": 456}]
|
|
|
|
def test_update_partial_add_row(self):
|
|
tbl = Table([{"a": "abc", "b": 123}], index="a")
|
|
tbl.update([{"a": "abc", "b": 456}, {"a": "def"}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": "abc", "b": 456},
|
|
{"a": "def", "b": None},
|
|
]
|
|
|
|
def test_update_partial_noop(self):
|
|
tbl = Table([{"a": "abc", "b": 1, "c": 2}], index="a")
|
|
tbl.update([{"a": "abc", "b": 456}])
|
|
assert tbl.view().to_records() == [{"a": "abc", "b": 456, "c": 2}]
|
|
|
|
def test_update_partial_unset(self):
|
|
tbl = Table(
|
|
[{"a": "abc", "b": 1, "c": 2}, {"a": "def", "b": 3, "c": 4}], index="a"
|
|
)
|
|
tbl.update([{"a": "abc"}, {"a": "def", "c": None}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": "abc", "b": 1, "c": 2},
|
|
{"a": "def", "b": 3, "c": None},
|
|
]
|
|
|
|
def test_update_columnar_partial_add_row(self):
|
|
tbl = Table([{"a": "abc", "b": 123}], index="a")
|
|
|
|
tbl.update({"a": ["abc", "def"], "b": [456, None]})
|
|
|
|
assert tbl.view().to_records() == [
|
|
{"a": "abc", "b": 456},
|
|
{"a": "def", "b": None},
|
|
]
|
|
|
|
def test_update_columnar_partial_noop(self):
|
|
tbl = Table([{"a": "abc", "b": 1, "c": 2}], index="a")
|
|
|
|
# no-op because "c" is not in the update dataset
|
|
tbl.update({"a": ["abc"], "b": [456]})
|
|
|
|
assert tbl.view().to_records() == [{"a": "abc", "b": 456, "c": 2}]
|
|
|
|
def test_update_columnar_partial_unset(self):
|
|
tbl = Table(
|
|
[{"a": "abc", "b": 1, "c": 2}, {"a": "def", "b": 3, "c": 4}], index="a"
|
|
)
|
|
|
|
tbl.update({"a": ["abc"], "b": [None]})
|
|
|
|
assert tbl.view().to_records() == [
|
|
{"a": "abc", "b": None, "c": 2},
|
|
{"a": "def", "b": 3, "c": 4},
|
|
]
|
|
|
|
def test_update_partial_subcolumn(self):
|
|
tbl = Table([{"a": "abc", "b": 123, "c": 456}], index="a")
|
|
tbl.update([{"a": "abc", "c": 1234}])
|
|
assert tbl.view().to_records() == [{"a": "abc", "b": 123, "c": 1234}]
|
|
|
|
def test_update_partial_subcolumn_dict(self):
|
|
tbl = Table([{"a": "abc", "b": 123, "c": 456}], index="a")
|
|
tbl.update({"a": ["abc"], "c": [1234]})
|
|
assert tbl.view().to_records() == [{"a": "abc", "b": 123, "c": 1234}]
|
|
|
|
def test_update_partial_cols_more_columns_than_table(self):
|
|
tbl = Table([{"a": "abc", "b": 123}], index="a")
|
|
tbl.update([{"a": "abc", "b": 456, "c": 789}])
|
|
assert tbl.view().to_records() == [{"a": "abc", "b": 456}]
|
|
|
|
def test_update_columnar_append(self):
|
|
tbl = Table({"a": ["abc"], "b": [123]})
|
|
tbl.update({"a": ["def"], "b": [456]})
|
|
assert tbl.view().to_records() == [
|
|
{"a": "abc", "b": 123},
|
|
{"a": "def", "b": 456},
|
|
]
|
|
|
|
def test_update_columnar_partial(self):
|
|
tbl = Table({"a": ["abc"], "b": [123]}, index="a")
|
|
tbl.update({"a": ["abc"], "b": [456]})
|
|
assert tbl.view().to_records() == [{"a": "abc", "b": 456}]
|
|
|
|
# make sure already created views are notified properly
|
|
def test_update_from_schema_notify(self):
|
|
tbl = Table({"a": "string", "b": "integer"})
|
|
view = tbl.view()
|
|
assert view.num_rows() == 0
|
|
tbl.update([{"a": "abc", "b": 123}])
|
|
assert view.to_records() == [{"a": "abc", "b": 123}]
|
|
|
|
def test_update_columnar_from_schema_notify(self):
|
|
tbl = Table({"a": "string", "b": "integer"})
|
|
view = tbl.view()
|
|
assert view.num_rows() == 0
|
|
tbl.update({"a": ["abc"], "b": [123]})
|
|
assert view.to_records() == [{"a": "abc", "b": 123}]
|
|
|
|
def test_update_append_notify(self):
|
|
tbl = Table([{"a": "abc", "b": 123}])
|
|
view = tbl.view()
|
|
assert view.num_rows() == 1
|
|
tbl.update([{"a": "def", "b": 456}])
|
|
assert view.to_records() == [{"a": "abc", "b": 123}, {"a": "def", "b": 456}]
|
|
|
|
def test_update_partial_notify(self):
|
|
tbl = Table([{"a": "abc", "b": 123}], index="a")
|
|
view = tbl.view()
|
|
assert view.num_rows() == 1
|
|
tbl.update([{"a": "abc", "b": 456}])
|
|
assert view.to_records() == [{"a": "abc", "b": 456}]
|
|
|
|
def test_update_partial_cols_not_in_schema_notify(self):
|
|
tbl = Table([{"a": "abc", "b": 123}], index="a")
|
|
view = tbl.view()
|
|
assert view.num_rows() == 1
|
|
tbl.update([{"a": "abc", "b": 456, "c": 789}])
|
|
assert view.to_records() == [{"a": "abc", "b": 456}]
|
|
|
|
def test_update_columnar_append_notify(self):
|
|
tbl = Table({"a": ["abc"], "b": [123]})
|
|
view = tbl.view()
|
|
assert view.num_rows() == 1
|
|
tbl.update({"a": ["def"], "b": [456]})
|
|
assert view.to_records() == [{"a": "abc", "b": 123}, {"a": "def", "b": 456}]
|
|
|
|
def test_update_columnar_partial_notify(self):
|
|
tbl = Table({"a": ["abc"], "b": [123]}, index="a")
|
|
view = tbl.view()
|
|
assert view.num_rows() == 1
|
|
tbl.update({"a": ["abc"], "b": [456]})
|
|
assert view.to_records() == [{"a": "abc", "b": 456}]
|
|
|
|
# bool
|
|
|
|
def test_update_bool_from_schema(self):
|
|
bool_data = [{"a": True, "b": False}, {"a": True, "b": True}]
|
|
tbl = Table({"a": "boolean", "b": "boolean"})
|
|
tbl.update(bool_data)
|
|
assert tbl.size() == 2
|
|
assert tbl.view().to_records() == bool_data
|
|
|
|
def test_update_bool_str_from_schema(self):
|
|
bool_data = [{"a": "True", "b": "False"}, {"a": "True", "b": "True"}]
|
|
tbl = Table({"a": "boolean", "b": "boolean"})
|
|
tbl.update(bool_data)
|
|
assert tbl.size() == 2
|
|
assert tbl.view().to_records() == [
|
|
{"a": True, "b": False},
|
|
{"a": True, "b": True},
|
|
]
|
|
|
|
@mark.skip(reason="We may not want to support this")
|
|
def test_update_bool_str_all_formats_from_schema(self):
|
|
bool_data = [
|
|
{"a": "True", "b": "False"},
|
|
{"a": "t", "b": "f"},
|
|
{"a": "true", "b": "false"},
|
|
{"a": 1, "b": 0},
|
|
{"a": "on", "b": "off"},
|
|
]
|
|
tbl = Table({"a": "boolean", "b": "boolean"})
|
|
tbl.update(bool_data)
|
|
assert tbl.size() == 5
|
|
assert tbl.view().to_columns() == {
|
|
"a": [True, True, True, True, True],
|
|
"b": [False, False, False, False, False],
|
|
}
|
|
|
|
def test_update_bool_int_from_schema(self):
|
|
bool_data = [{"a": 1, "b": 0}, {"a": 1, "b": 0}]
|
|
tbl = Table({"a": "boolean", "b": "boolean"})
|
|
tbl.update(bool_data)
|
|
assert tbl.size() == 2
|
|
assert tbl.view().to_columns() == {"a": [True, True], "b": [False, False]}
|
|
|
|
# dates and datetimes
|
|
def test_update_date(self, util):
|
|
tbl = Table({"a": [date(2019, 7, 11)]})
|
|
tbl.update([{"a": date(2019, 7, 12)}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 11))},
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12))},
|
|
]
|
|
|
|
@mark.skip # We do not support numpy.
|
|
def test_update_date_np(self, util):
|
|
tbl = Table({"a": [date(2019, 7, 11)]})
|
|
tbl.update([{"a": np.datetime64(date(2019, 7, 12))}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 11))},
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12))},
|
|
]
|
|
|
|
def test_update_datetime(self, util):
|
|
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)]})
|
|
tbl.update([{"a": datetime(2019, 7, 12, 11, 0)}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 11, 11, 0))},
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12, 11, 0))},
|
|
]
|
|
|
|
@mark.skip # We do not support numpy.
|
|
def test_update_datetime_np(self, util):
|
|
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)]})
|
|
tbl.update([{"a": np.datetime64(datetime(2019, 7, 12, 11, 0))}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 11, 11, 0))},
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12, 11, 0))},
|
|
]
|
|
|
|
@mark.skip # We do not support numpy.
|
|
def test_update_datetime_np_ts(self, util):
|
|
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)]})
|
|
tbl.update([{"a": np.datetime64("2019-07-12T11:00")}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 11, 11, 0))},
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12, 11, 0))},
|
|
]
|
|
|
|
def test_update_datetime_timestamp_seconds(self, util):
|
|
ts = util.to_timestamp(datetime(2019, 7, 12, 11, 0, 0))
|
|
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)]})
|
|
tbl.update([{"a": ts}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 11, 11, 0))},
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12, 11, 0))},
|
|
]
|
|
|
|
def test_update_datetime_timestamp_ms(self, util):
|
|
ts = util.to_timestamp(datetime(2019, 7, 12, 11, 0, 0))
|
|
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)]})
|
|
tbl.update([{"a": ts}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 11, 11, 0))},
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12, 11, 0))},
|
|
]
|
|
|
|
# partial date & datetime updates
|
|
|
|
def test_update_date_partial(self, util):
|
|
tbl = Table({"a": [date(2019, 7, 11)], "b": [1]}, index="b")
|
|
tbl.update([{"a": date(2019, 7, 12), "b": 1}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12)), "b": 1}
|
|
]
|
|
|
|
@mark.skip # We do not support numpy anymore.
|
|
def test_update_date_np_partial(self, util):
|
|
tbl = Table({"a": [date(2019, 7, 11)], "b": [1]}, index="b")
|
|
tbl.update([{"a": np.datetime64(date(2019, 7, 12)), "b": 1}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12)), "b": 1}
|
|
]
|
|
|
|
def test_update_datetime_partial(self, util):
|
|
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)], "b": [1]}, index="b")
|
|
tbl.update([{"a": datetime(2019, 7, 12, 11, 0), "b": 1}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12, 11, 0)), "b": 1}
|
|
]
|
|
|
|
@mark.skip # We do not support numpy anymore.
|
|
def test_update_datetime_np_partial(self, util):
|
|
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)], "b": [1]}, index="b")
|
|
tbl.update([{"a": np.datetime64(datetime(2019, 7, 12, 11, 0)), "b": 1}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12, 11, 0)), "b": 1}
|
|
]
|
|
|
|
@mark.skip # We do not support numpy anymore.
|
|
def test_update_datetime_np_ts_partial(self, util):
|
|
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)], "b": [1]}, index="b")
|
|
tbl.update([{"a": np.datetime64("2019-07-12T11:00"), "b": 1}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12, 11, 0)), "b": 1}
|
|
]
|
|
|
|
def test_update_datetime_timestamp_seconds_partial(self, util):
|
|
ts = util.to_timestamp(datetime(2019, 7, 12, 11, 0, 0))
|
|
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)], "idx": [1]}, index="idx")
|
|
tbl.update([{"a": ts, "idx": 1}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12, 11, 0)), "idx": 1}
|
|
]
|
|
|
|
def test_update_datetime_timestamp_ms_partial(self, util):
|
|
ts = util.to_timestamp(datetime(2019, 7, 12, 11, 0, 0))
|
|
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)], "idx": [1]}, index="idx")
|
|
tbl.update([{"a": ts, "idx": 1}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12, 11, 0)), "idx": 1}
|
|
]
|
|
|
|
# updating dates using implicit index
|
|
|
|
def test_update_date_partial_implicit(self, util):
|
|
tbl = Table({"a": [date(2019, 7, 11)]})
|
|
tbl.update([{"a": date(2019, 7, 12), "__INDEX__": 0}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12))}
|
|
]
|
|
|
|
@mark.skip # We do not support numpy anymore.
|
|
def test_update_date_np_partial_implicit(self, util):
|
|
tbl = Table({"a": [date(2019, 7, 11)]})
|
|
tbl.update([{"a": np.datetime64(date(2019, 7, 12)), "__INDEX__": 0}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12))}
|
|
]
|
|
|
|
def test_update_datetime_partial_implicit(self, util):
|
|
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)]})
|
|
tbl.update([{"a": datetime(2019, 7, 12, 11, 0), "__INDEX__": 0}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12, 11, 0))}
|
|
]
|
|
|
|
@mark.skip # We do not support numpy anymore.
|
|
def test_update_datetime_np_partial_implicit(self, util):
|
|
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)]})
|
|
tbl.update([{"a": np.datetime64(datetime(2019, 7, 12, 11, 0)), "__INDEX__": 0}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12, 11, 0))}
|
|
]
|
|
|
|
@mark.skip # We do not support numpy anymore.
|
|
def test_update_datetime_np_ts_partial_implicit(self, util):
|
|
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)]})
|
|
tbl.update([{"a": np.datetime64("2019-07-12T11:00"), "__INDEX__": 0}])
|
|
assert tbl.view().to_records() == [
|
|
{"a": util.to_timestamp(datetime(2019, 7, 12, 11, 0))}
|
|
]
|
|
|
|
# implicit index
|
|
|
|
def test_update_implicit_index(self):
|
|
data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}]
|
|
tbl = Table(data)
|
|
view = tbl.view()
|
|
tbl.update([{"__INDEX__": 0, "a": 3, "b": 15}])
|
|
assert view.to_records() == [{"a": 3, "b": 15}, {"a": 2, "b": 3}]
|
|
|
|
def test_update_implicit_index_dict_noop(self):
|
|
data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}]
|
|
tbl = Table(data)
|
|
view = tbl.view()
|
|
|
|
# "b" does not exist in dataset, so no-op
|
|
tbl.update(
|
|
{
|
|
"__INDEX__": [0],
|
|
"a": [3],
|
|
}
|
|
)
|
|
assert view.to_records() == [{"a": 3, "b": 2}, {"a": 2, "b": 3}]
|
|
|
|
def test_update_implicit_index_dict_unset_with_null(self):
|
|
data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}]
|
|
tbl = Table(data)
|
|
view = tbl.view()
|
|
|
|
# unset because "b" is null
|
|
tbl.update({"__INDEX__": [0], "a": [3], "b": [None]})
|
|
assert view.to_records() == [{"a": 3, "b": None}, {"a": 2, "b": 3}]
|
|
|
|
def test_update_implicit_index_multi(self):
|
|
data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}, {"a": 4, "b": 5}]
|
|
tbl = Table(data)
|
|
view = tbl.view()
|
|
tbl.update(
|
|
[
|
|
{
|
|
"__INDEX__": 0,
|
|
"a": 3,
|
|
},
|
|
{"__INDEX__": 2, "a": 5},
|
|
]
|
|
)
|
|
assert view.to_records() == [
|
|
{"a": 3, "b": 2},
|
|
{"a": 2, "b": 3},
|
|
{"a": 5, "b": 5},
|
|
]
|
|
|
|
def test_update_implicit_index_symmetric(self):
|
|
data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}]
|
|
tbl = Table(data)
|
|
view = tbl.view()
|
|
records = view.to_records(index=True)
|
|
idx = records[0]["__INDEX__"][0] # XXX: How should we grab this?
|
|
tbl.update([{"__INDEX__": idx, "a": 3}])
|
|
assert view.to_records() == [{"a": 3, "b": 2}, {"a": 2, "b": 3}]
|
|
|
|
def test_update_explicit_index(self):
|
|
data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}]
|
|
tbl = Table(data, index="a")
|
|
view = tbl.view()
|
|
tbl.update([{"a": 1, "b": 3}])
|
|
assert view.to_records() == [{"a": 1, "b": 3}, {"a": 2, "b": 3}]
|
|
|
|
def test_update_explicit_index_multi(self):
|
|
data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}, {"a": 3, "b": 4}]
|
|
tbl = Table(data, index="a")
|
|
view = tbl.view()
|
|
tbl.update([{"a": 1, "b": 3}, {"a": 3, "b": 5}])
|
|
assert view.to_records() == [
|
|
{"a": 1, "b": 3},
|
|
{"a": 2, "b": 3},
|
|
{"a": 3, "b": 5},
|
|
]
|
|
|
|
def test_update_explicit_index_multi_append(self):
|
|
data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}, {"a": 3, "b": 4}]
|
|
tbl = Table(data, index="a")
|
|
view = tbl.view()
|
|
tbl.update([{"a": 1, "b": 3}, {"a": 12, "b": 5}])
|
|
assert view.to_records() == [
|
|
{"a": 1, "b": 3},
|
|
{"a": 2, "b": 3},
|
|
{"a": 3, "b": 4},
|
|
{"a": 12, "b": 5},
|
|
]
|
|
|
|
def test_update_explicit_index_multi_append_noindex(self):
|
|
data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}, {"a": 3, "b": 4}]
|
|
tbl = Table(data, index="a")
|
|
view = tbl.view()
|
|
tbl.update([{"a": 1, "b": 3}, {"b": 5}])
|
|
assert view.to_records() == [
|
|
{"a": None, "b": 5},
|
|
{"a": 1, "b": 3},
|
|
{"a": 2, "b": 3},
|
|
{"a": 3, "b": 4},
|
|
]
|
|
|
|
def test_update_implicit_index_with_explicit_unset(self):
|
|
data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}]
|
|
tbl = Table(data, index="a")
|
|
view = tbl.view()
|
|
tbl.update([{"__INDEX__": 1, "b": 3}])
|
|
assert view.to_records() == [{"a": 1, "b": 3}, {"a": 2, "b": 3}]
|
|
|
|
def test_update_implicit_index_with_explicit_set(self):
|
|
data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}]
|
|
tbl = Table(data, index="a")
|
|
view = tbl.view()
|
|
tbl.update(
|
|
[{"__INDEX__": 1, "a": 1, "b": 3}]
|
|
) # should ignore re-specification of pkey
|
|
assert view.to_records() == [{"a": 1, "b": 3}, {"a": 2, "b": 3}]
|