@@ -3145,15 +3145,25 @@ class Table(Fixed):
31453145 info : Dict
31463146
31473147 def __init__ (
3148- self , parent : HDFStore , group : "Node" , encoding = None , errors : str = "strict"
3148+ self ,
3149+ parent : HDFStore ,
3150+ group : "Node" ,
3151+ encoding = None ,
3152+ errors : str = "strict" ,
3153+ index_axes = None ,
3154+ non_index_axes = None ,
3155+ values_axes = None ,
3156+ data_columns = None ,
3157+ info = None ,
3158+ nan_rep = None ,
31493159 ):
31503160 super ().__init__ (parent , group , encoding = encoding , errors = errors )
3151- self .index_axes = []
3152- self .non_index_axes = []
3153- self .values_axes = []
3154- self .data_columns = []
3155- self .info = dict ()
3156- self .nan_rep = None
3161+ self .index_axes = index_axes or []
3162+ self .non_index_axes = non_index_axes or []
3163+ self .values_axes = values_axes or []
3164+ self .data_columns = data_columns or []
3165+ self .info = info or dict ()
3166+ self .nan_rep = nan_rep
31573167
31583168 @property
31593169 def table_type_short (self ) -> str :
@@ -3635,23 +3645,28 @@ def _create_axes(
36353645 data_columns = None ,
36363646 min_itemsize = None ,
36373647 ):
3638- """ create and return the axes
3639- legacy tables create an indexable column, indexable index,
3640- non-indexable fields
3641-
3642- Parameters
3643- ----------
3644- axes: a list of the axes in order to create (names or numbers of
3645- the axes)
3646- obj : the object to create axes on
3647- validate: validate the obj against an existing object already
3648- written
3649- min_itemsize: a dict of the min size for a column in bytes
3650- nan_rep : a values to use for string column nan_rep
3651- encoding : the encoding for string values
3652- data_columns : a list of columns that we want to create separate to
3653- allow indexing (or True will force all columns)
3648+ """
3649+ Create and return the axes.
3650+
3651+ Parameters
3652+ ----------
3653+ axes: list or None
3654+ The names or numbers of the axes to create.
3655+ obj : DataFrame
3656+ The object to create axes on.
3657+ validate: bool, default True
3658+ Whether to validate the obj against an existing object already written.
3659+ nan_rep :
3660+ A value to use for string column nan_rep.
3661+ data_columns : List[str], True, or None, default None
3662+ Specify the columns that we want to create to allow indexing on.
36543663
3664+ * True : Use all available columns.
3665+ * None : Use no columns.
3666+ * List[str] : Use the specified columns.
3667+
3668+ min_itemsize: Dict[str, int] or None, default None
3669+ The min itemsize for a column in bytes.
36553670 """
36563671
36573672 if not isinstance (obj , DataFrame ):
@@ -3670,15 +3685,15 @@ def _create_axes(
36703685
36713686 # do we have an existing table (if so, use its axes & data_columns)
36723687 if self .infer_axes ():
3673- existing_table = self . copy ()
3688+ table_exists = True
36743689 axes = [a .axis for a in self .index_axes ]
3675- data_columns = self .data_columns
3690+ data_columns = list ( self .data_columns )
36763691 nan_rep = self .nan_rep
3677- new_info = self .info
36783692 # TODO: do we always have validate=True here?
36793693 else :
3680- existing_table = None
3681- new_info = self .info
3694+ table_exists = False
3695+
3696+ new_info = self .info
36823697
36833698 assert self .ndim == 2 # with next check, we must have len(axes) == 1
36843699 # currently support on ndim-1 axes
@@ -3700,9 +3715,9 @@ def _create_axes(
37003715 a = obj .axes [idx ]
37013716 # we might be able to change the axes on the appending data if necessary
37023717 append_axis = list (a )
3703- if existing_table is not None :
3718+ if table_exists :
37043719 indexer = len (new_non_index_axes ) # i.e. 0
3705- exist_axis = existing_table .non_index_axes [indexer ][1 ]
3720+ exist_axis = self .non_index_axes [indexer ][1 ]
37063721 if not array_equivalent (np .array (append_axis ), np .array (exist_axis )):
37073722
37083723 # ahah! -> reindex
@@ -3721,8 +3736,8 @@ def _create_axes(
37213736 # Now we can construct our new index axis
37223737 idx = axes [0 ]
37233738 a = obj .axes [idx ]
3724- index_name = obj ._AXIS_NAMES [idx ]
3725- new_index = _convert_index (index_name , a , self .encoding , self .errors )
3739+ axis_name = obj ._AXIS_NAMES [idx ]
3740+ new_index = _convert_index (axis_name , a , self .encoding , self .errors )
37263741 new_index .axis = idx
37273742
37283743 # Because we are always 2D, there is only one new_index, so
@@ -3749,9 +3764,11 @@ def get_blk_items(mgr, blocks):
37493764 data_columns = self .validate_data_columns (
37503765 data_columns , min_itemsize , new_non_index_axes
37513766 )
3767+
37523768 block_obj = self .get_object (obj , transposed )._consolidate ()
3769+
37533770 blocks , blk_items = self ._get_blocks_and_items (
3754- block_obj , existing_table , new_non_index_axes , data_columns
3771+ block_obj , table_exists , new_non_index_axes , self . values_axes , data_columns
37553772 )
37563773
37573774 # add my values
@@ -3772,13 +3789,15 @@ def get_blk_items(mgr, blocks):
37723789
37733790 # make sure that we match up the existing columns
37743791 # if we have an existing table
3775- if existing_table is not None and validate :
3792+ existing_col : Optional [DataCol ]
3793+
3794+ if table_exists and validate :
37763795 try :
3777- existing_col = existing_table .values_axes [i ]
3796+ existing_col = self .values_axes [i ]
37783797 except (IndexError , KeyError ):
37793798 raise ValueError (
37803799 f"Incompatible appended table [{ blocks } ]"
3781- f"with existing table [{ existing_table .values_axes } ]"
3800+ f"with existing table [{ self .values_axes } ]"
37823801 )
37833802 else :
37843803 existing_col = None
@@ -3827,22 +3846,34 @@ def get_blk_items(mgr, blocks):
38273846
38283847 j += 1
38293848
3830- self .nan_rep = nan_rep
3831- self .data_columns = [col .name for col in vaxes if col .is_data_indexable ]
3832- self .values_axes = vaxes
3833- self .index_axes = new_index_axes
3834- self .non_index_axes = new_non_index_axes
3849+ dcs = [col .name for col in vaxes if col .is_data_indexable ]
38353850
3836- # validate our min_itemsize
3837- self .validate_min_itemsize (min_itemsize )
3851+ new_table = type (self )(
3852+ parent = self .parent ,
3853+ group = self .group ,
3854+ encoding = self .encoding ,
3855+ errors = self .errors ,
3856+ index_axes = new_index_axes ,
3857+ non_index_axes = new_non_index_axes ,
3858+ values_axes = vaxes ,
3859+ data_columns = dcs ,
3860+ info = new_info ,
3861+ nan_rep = nan_rep ,
3862+ )
3863+ if hasattr (self , "levels" ):
3864+ # TODO: get this into constructor, only for appropriate subclass
3865+ new_table .levels = self .levels
3866+
3867+ new_table .validate_min_itemsize (min_itemsize )
3868+
3869+ if validate and table_exists :
3870+ new_table .validate (self )
38383871
3839- # validate the axes if we have an existing table
3840- if validate :
3841- self .validate (existing_table )
3872+ return new_table
38423873
38433874 @staticmethod
38443875 def _get_blocks_and_items (
3845- block_obj , existing_table , new_non_index_axes , data_columns
3876+ block_obj , table_exists , new_non_index_axes , values_axes , data_columns
38463877 ):
38473878 # Helper to clarify non-state-altering parts of _create_axes
38483879
@@ -3864,15 +3895,15 @@ def get_blk_items(mgr, blocks):
38643895 blocks .extend (mgr .blocks )
38653896 blk_items .extend (get_blk_items (mgr , mgr .blocks ))
38663897
3867- # reorder the blocks in the same order as the existing_table if we can
3868- if existing_table is not None :
3898+ # reorder the blocks in the same order as the existing table if we can
3899+ if table_exists :
38693900 by_items = {
38703901 tuple (b_items .tolist ()): (b , b_items )
38713902 for b , b_items in zip (blocks , blk_items )
38723903 }
38733904 new_blocks = []
38743905 new_blk_items = []
3875- for ea in existing_table . values_axes :
3906+ for ea in values_axes :
38763907 items = tuple (ea .values )
38773908 try :
38783909 b , b_items = by_items .pop (items )
@@ -4103,7 +4134,7 @@ def write(
41034134 self ._handle .remove_node (self .group , "table" )
41044135
41054136 # create the axes
4106- self ._create_axes (
4137+ table = self ._create_axes (
41074138 axes = axes ,
41084139 obj = obj ,
41094140 validate = append ,
@@ -4112,34 +4143,34 @@ def write(
41124143 data_columns = data_columns ,
41134144 )
41144145
4115- for a in self .axes :
4146+ for a in table .axes :
41164147 a .validate_names ()
41174148
4118- if not self .is_exists :
4149+ if not table .is_exists :
41194150
41204151 # create the table
4121- options = self .create_description (
4152+ options = table .create_description (
41224153 complib = complib ,
41234154 complevel = complevel ,
41244155 fletcher32 = fletcher32 ,
41254156 expectedrows = expectedrows ,
41264157 )
41274158
41284159 # set the table attributes
4129- self .set_attrs ()
4160+ table .set_attrs ()
41304161
41314162 # create the table
4132- self ._handle .create_table (self .group , ** options )
4163+ table ._handle .create_table (table .group , ** options )
41334164
41344165 # update my info
4135- self .attrs .info = self .info
4166+ table .attrs .info = table .info
41364167
41374168 # validate the axes and set the kinds
4138- for a in self .axes :
4139- a .validate_and_set (self , append )
4169+ for a in table .axes :
4170+ a .validate_and_set (table , append )
41404171
41414172 # add the rows
4142- self .write_data (chunksize , dropna = dropna )
4173+ table .write_data (chunksize , dropna = dropna )
41434174
41444175 def write_data (self , chunksize : Optional [int ], dropna : bool = False ):
41454176 """ we form the data into a 2-d including indexes,values,mask
0 commit comments