-
Notifications
You must be signed in to change notification settings - Fork 81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat!: Add TableDefinition wrapper for python #5892
Changes from 20 commits
8105b15
7ae04cd
c08506c
a57fe4e
4c08531
8d18f68
3ed4b41
3780ab4
8dbe38c
cfa737f
d1fca92
ed162af
7da0650
474a71f
52a404a
0053787
e42c7ae
84c6de7
81229ea
13b3cf0
835c2fc
0b9103c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,16 +4,17 @@ | |
|
||
""" This module implements the Column class and functions that work with Columns. """ | ||
|
||
from dataclasses import dataclass, field | ||
from enum import Enum | ||
from typing import Sequence, Any | ||
from functools import cached_property | ||
from typing import Sequence, Any, Optional | ||
from warnings import warn | ||
|
||
import jpy | ||
|
||
import deephaven.dtypes as dtypes | ||
from deephaven import DHError | ||
from deephaven.dtypes import DType | ||
from deephaven.dtypes import _instant_array | ||
from deephaven.dtypes import DType, _instant_array, from_jtype | ||
from deephaven._wrapper import JObjectWrapper | ||
|
||
_JColumnHeader = jpy.get_type("io.deephaven.qst.column.header.ColumnHeader") | ||
_JColumn = jpy.get_type("io.deephaven.qst.column.Column") | ||
|
@@ -32,46 +33,151 @@ def __repr__(self): | |
return self.name | ||
|
||
|
||
@dataclass | ||
class Column: | ||
""" A Column object represents a column definition in a Deephaven Table. """ | ||
name: str | ||
data_type: DType | ||
component_type: DType = None | ||
column_type: ColumnType = ColumnType.NORMAL | ||
class ColumnDefinition(JObjectWrapper): | ||
"""A Deephaven column definition.""" | ||
|
||
@property | ||
def j_column_header(self): | ||
return _JColumnHeader.of(self.name, self.data_type.qst_type) | ||
j_object_type = _JColumnDefinition | ||
|
||
def __init__(self, j_column_definition: jpy.JType): | ||
self.j_column_definition = j_column_definition | ||
|
||
@property | ||
def j_column_definition(self): | ||
if hasattr(self.data_type.j_type, 'jclass'): | ||
j_data_type = self.data_type.j_type.jclass | ||
else: | ||
j_data_type = self.data_type.qst_type.clazz() | ||
j_component_type = self.component_type.qst_type.clazz() if self.component_type else None | ||
j_column_type = self.column_type.value | ||
return _JColumnDefinition.fromGenericType(self.name, j_data_type, j_component_type, j_column_type) | ||
|
||
|
||
@dataclass | ||
class InputColumn(Column): | ||
""" An InputColumn represents a user defined column with some input data. """ | ||
input_data: Any = field(default=None) | ||
|
||
def __post_init__(self): | ||
def j_object(self) -> jpy.JType: | ||
return self.j_column_definition | ||
|
||
@cached_property | ||
def name(self) -> str: | ||
chipkent marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"""The column name.""" | ||
return self.j_column_definition.getName() | ||
|
||
@cached_property | ||
def data_type(self) -> DType: | ||
chipkent marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"""The column data type.""" | ||
return from_jtype(self.j_column_definition.getDataType()) | ||
|
||
@cached_property | ||
def component_type(self) -> Optional[DType]: | ||
"""The column component type.""" | ||
return from_jtype(self.j_column_definition.getComponentType()) | ||
|
||
@cached_property | ||
def column_type(self) -> ColumnType: | ||
chipkent marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"""The column type.""" | ||
return ColumnType(self.j_column_definition.getColumnType()) | ||
|
||
|
||
class Column(ColumnDefinition): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be a breaking change to remove, as users may be relying on the Column constructor, for example some_method([Column("Foo", dtypes.int32), Column("Bar", dtypes.str)]) I would be in favor of deprecating for eventual removal, suggesting users use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm ok with deprecation with a plan to remove in the next release. Create a ticket for removal and assign it to one of us. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
"""A Column object represents a column definition in a Deephaven Table. Deprecated for removal next release, prefer col_def.""" | ||
|
||
def __init__( | ||
self, | ||
name: str, | ||
data_type: DType, | ||
component_type: DType = None, | ||
column_type: ColumnType = ColumnType.NORMAL, | ||
): | ||
"""Deprecated for removal next release, prefer col_def.""" | ||
warn( | ||
"Column is deprecated for removal next release, prefer col_def", | ||
DeprecationWarning, | ||
stacklevel=2, | ||
) | ||
super().__init__( | ||
col_def(name, data_type, component_type, column_type).j_column_definition | ||
) | ||
|
||
|
||
class InputColumn: | ||
devinrsmith marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"""An InputColumn represents a user defined column with some input data.""" | ||
|
||
def __init__( | ||
chipkent marked this conversation as resolved.
Show resolved
Hide resolved
|
||
self, | ||
name: str = None, | ||
data_type: DType = None, | ||
component_type: DType = None, | ||
column_type: ColumnType = ColumnType.NORMAL, | ||
input_data: Any = None, | ||
): | ||
"""Creates an InputColumn. | ||
Args: | ||
name (str): the column name | ||
data_type (DType): the column data type | ||
component_type (Optional[DType]): the column component type, None by default | ||
column_type (ColumnType): the column type, NORMAL by default | ||
input_data: Any: the input data, by default is None | ||
|
||
Returns: | ||
a new InputColumn | ||
|
||
Raises: | ||
DHError | ||
""" | ||
devinrsmith marked this conversation as resolved.
Show resolved
Hide resolved
|
||
try: | ||
if self.input_data is None: | ||
self.j_column = _JColumn.empty(self.j_column_header) | ||
else: | ||
if self.data_type.is_primitive: | ||
self.j_column = _JColumn.ofUnsafe(self.name, dtypes.array(self.data_type, self.input_data, | ||
remap=dtypes.null_remap(self.data_type))) | ||
else: | ||
self.j_column = _JColumn.of(self.j_column_header, dtypes.array(self.data_type, self.input_data)) | ||
self._column_definition = col_def( | ||
name, data_type, component_type, column_type | ||
) | ||
self.j_column = self._to_j_column(input_data) | ||
except Exception as e: | ||
raise DHError(e, f"failed to create an InputColumn ({self.name}).") from e | ||
raise DHError(e, f"failed to create an InputColumn ({name}).") from e | ||
|
||
def _to_j_column(self, input_data: Any = None) -> jpy.JType: | ||
devinrsmith marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if input_data is None: | ||
return _JColumn.empty( | ||
_JColumnHeader.of( | ||
self._column_definition.name, | ||
self._column_definition.data_type.qst_type, | ||
) | ||
) | ||
if self._column_definition.data_type.is_primitive: | ||
return _JColumn.ofUnsafe( | ||
self._column_definition.name, | ||
dtypes.array( | ||
self._column_definition.data_type, | ||
input_data, | ||
remap=dtypes.null_remap(self._column_definition.data_type), | ||
), | ||
) | ||
return _JColumn.of( | ||
_JColumnHeader.of( | ||
self._column_definition.name, self._column_definition.data_type.qst_type | ||
), | ||
dtypes.array(self._column_definition.data_type, input_data), | ||
) | ||
|
||
|
||
def col_def( | ||
name: str, | ||
data_type: DType, | ||
component_type: Optional[DType] = None, | ||
column_type: ColumnType = ColumnType.NORMAL, | ||
) -> ColumnDefinition: | ||
"""Creates a ColumnDefinition. | ||
|
||
Args: | ||
name (str): the column name | ||
data_type (DType): the column data type | ||
component_type (Optional[DType]): the column component type, None by default | ||
column_type (ColumnType): the column type, ColumnType.NORMAL by default | ||
|
||
Returns: | ||
a new ColumnDefinition | ||
|
||
Raises: | ||
DHError | ||
""" | ||
try: | ||
return ColumnDefinition( | ||
_JColumnDefinition.fromGenericType( | ||
name, | ||
data_type.j_type.jclass | ||
if hasattr(data_type.j_type, "jclass") | ||
else data_type.qst_type.clazz(), | ||
component_type.qst_type.clazz() if component_type else None, | ||
column_type.value, | ||
) | ||
) | ||
except Exception as e: | ||
raise DHError(e, f"failed to create a ColumnDefinition ({name}).") from e | ||
|
||
|
||
def bool_col(name: str, data: Sequence) -> InputColumn: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pydoc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we pydoc any of our
j_object
property methods?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so, but do a quick check.