diff --git a/app/models/address_models.py b/app/models/address_models.py index 69e142a..b24af71 100644 --- a/app/models/address_models.py +++ b/app/models/address_models.py @@ -1,6 +1,6 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union +from typing import Dict, List, Optional, Set, Union, ClassVar from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import get_id_random, redis_lookup_id_random @@ -120,6 +120,11 @@ class Address_Base(BaseModel): return values + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'country_subdivision_name', 'country_name' + ] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = False diff --git a/app/models/common_field_schema.py b/app/models/common_field_schema.py index 20788ff..0615d58 100644 --- a/app/models/common_field_schema.py +++ b/app/models/common_field_schema.py @@ -49,6 +49,7 @@ base_fields['event_person_tracking_id_random'] = xxx_id_random_field_schema base_fields['event_presentation_id_random'] = xxx_id_random_field_schema base_fields['event_presenter_id_random'] = xxx_id_random_field_schema base_fields['event_registration_id_random'] = xxx_id_random_field_schema +base_fields['event_registration_cfg_id_random'] = xxx_id_random_field_schema base_fields['event_session_id_random'] = xxx_id_random_field_schema base_fields['event_track_id_random'] = xxx_id_random_field_schema base_fields['flask_cfg_id_random'] = xxx_id_random_field_schema diff --git a/app/models/contact_models.py b/app/models/contact_models.py index 47f022e..771e970 100644 --- a/app/models/contact_models.py +++ b/app/models/contact_models.py @@ -1,6 +1,6 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union +from typing import Dict, List, Optional, Set, Union, ClassVar from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import get_id_random, redis_lookup_id_random @@ -139,6 +139,11 @@ class Contact_Base(BaseModel): return values + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'linked_address_id', 'timezone_name', 'address' + ] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = False diff --git a/app/models/event_abstract_models.py b/app/models/event_abstract_models.py index 6d20f66..1679ef5 100644 --- a/app/models/event_abstract_models.py +++ b/app/models/event_abstract_models.py @@ -1,6 +1,6 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union +from typing import Dict, List, Optional, Set, Union, ClassVar from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import redis_lookup_id_random @@ -27,6 +27,7 @@ class Event_Abstract_Base(BaseModel): id: Optional[str] = Field(None, **base_fields['event_abstract_id_random']) event_abstract_id: Optional[str] = Field(None, **base_fields['event_abstract_id_random']) + account_id: Optional[str] = Field(None, **base_fields['account_id_random']) event_id: Optional[str] = Field(None, **base_fields['event_id_random']) event_person_id: Optional[str] = Field(None, **base_fields['event_person_id_random']) event_presentation_id: Optional[str] = Field(None, **base_fields['event_presentation_id_random']) @@ -96,6 +97,8 @@ class Event_Abstract_Base(BaseModel): values['id'] = rid values['event_abstract_id'] = rid + if a_rid := values.get('account_id_random'): + values['account_id'] = a_rid if e_rid := values.get('event_id_random'): values['event_id'] = e_rid if ep_rid := values.get('event_person_id_random'): @@ -110,12 +113,18 @@ class Event_Abstract_Base(BaseModel): values['grant_id'] = g_rid # 2. Prevent "Collision Population" - for k in ['id', 'event_abstract_id', 'event_id', 'event_person_id', 'event_presentation_id', 'event_presenter_id', 'event_session_id', 'grant_id']: + for k in ['id', 'event_abstract_id', 'account_id', 'event_id', 'event_person_id', 'event_presentation_id', 'event_presenter_id', 'event_session_id', 'grant_id']: if k in values and not isinstance(values[k], str) and values[k] is not None: del values[k] return values + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'account_id', 'event_session_code', 'event_session_name', + 'event_file_list', 'event_person', 'event_presenter_list' + ] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = False @@ -136,6 +145,7 @@ class Event_Abstract_Base_New(Core_Std_Obj_Base): id: Optional[str] = Field(None, **base_fields['event_abstract_id_random']) event_abstract_id: Optional[str] = Field(None, **base_fields['event_abstract_id_random']) + account_id: Optional[str] = Field(None, **base_fields['account_id_random']) event_id: Optional[str] = Field(None, **base_fields['event_id_random']) event_person_id: Optional[str] = Field(None, **base_fields['event_person_id_random']) event_presentation_id: Optional[str] = Field(None, **base_fields['event_presentation_id_random']) @@ -181,6 +191,8 @@ class Event_Abstract_Base_New(Core_Std_Obj_Base): values['id'] = rid values['event_abstract_id'] = rid + if a_rid := values.get('account_id_random'): + values['account_id'] = a_rid if e_rid := values.get('event_id_random'): values['event_id'] = e_rid if ep_rid := values.get('event_person_id_random'): @@ -195,12 +207,17 @@ class Event_Abstract_Base_New(Core_Std_Obj_Base): values['grant_id'] = g_rid # 2. Prevent "Collision Population" - for k in ['id', 'event_abstract_id', 'event_id', 'event_person_id', 'event_presentation_id', 'event_presenter_id', 'event_session_id', 'grant_id']: + for k in ['id', 'event_abstract_id', 'account_id', 'event_id', 'event_person_id', 'event_presentation_id', 'event_presenter_id', 'event_session_id', 'grant_id']: if k in values and not isinstance(values[k], str) and values[k] is not None: del values[k] return values + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'account_id' + ] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = False @@ -246,4 +263,9 @@ class Event_Abstract_Ext(Event_Abstract_Base_New): # event_track: Optional[Event_Track_Base] # poc_event_person: Optional[Event_Person_Base] # Maybe change this to primary_event_person? # poc_person: Optional[Person_Base] # Maybe change this to primary_person? + + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = Event_Abstract_Base_New.fields_to_exclude_from_db + [ + 'event_session_code', 'event_session_name', 'event_cfg', 'event_file_list', 'event_person' + ] # ### END ### API Event Abstract Models ### Event_Abstract_Ext() ### diff --git a/app/models/event_badge_models.py b/app/models/event_badge_models.py index 028c858..d5f5894 100644 --- a/app/models/event_badge_models.py +++ b/app/models/event_badge_models.py @@ -1,6 +1,6 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union +from typing import Dict, List, Optional, Set, Union, ClassVar from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import redis_lookup_id_random @@ -191,6 +191,11 @@ class Event_Badge_Base(BaseModel): _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'account_id', 'order', 'ticket_list', 'event_badge_template' + ] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = True @@ -329,6 +334,11 @@ class Event_Badge_Basic_Base(BaseModel): _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'account_id', 'event_badge_template' + ] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = True diff --git a/app/models/event_cfg_models.py b/app/models/event_cfg_models.py index 916ef40..ead1ce3 100644 --- a/app/models/event_cfg_models.py +++ b/app/models/event_cfg_models.py @@ -1,7 +1,7 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union -from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator +from typing import Dict, List, Optional, Set, Union, ClassVar +from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import redis_lookup_id_random from app.lib_general import log, logging @@ -15,16 +15,40 @@ class Event_Cfg_Base(BaseModel): log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) - id_random: Optional[str] = Field( - # **base_fields['event_cfg_id_random'], - alias = 'event_cfg_id_random', - ) - id: Optional[int] = Field( - alias = 'event_cfg_id' - ) + # --- Standardized Vision IDs (Strings) --- + id: Optional[str] = Field(None, **base_fields['event_cfg_id_random']) + event_cfg_id: Optional[str] = Field(None, **base_fields['event_cfg_id_random']) - event_id_random: Optional[str] - event_id: Optional[int] + account_id: Optional[str] = Field(None, **base_fields['account_id_random']) + event_id: Optional[str] = Field(None, **base_fields['event_id_random']) + + # --- Standardized Legacy / Internal IDs (Excluded) --- + id_random: Optional[str] = Field(None, alias='event_cfg_id_random', exclude=True) + account_id_random: Optional[str] = Field(None, exclude=True) + event_id_random: Optional[str] = Field(None, exclude=True) + + @root_validator(pre=True) + def map_v3_ids(cls, values): + """ + Vision Transformer: + Map DB keys to clean API keys and strip internal integers. + """ + # 1. Map Random Strings to Clean Names + if rid := values.get('id_random') or values.get('event_cfg_id_random'): + values['id'] = rid + values['event_cfg_id'] = rid + + if a_rid := values.get('account_id_random'): + values['account_id'] = a_rid + if e_rid := values.get('event_id_random'): + values['event_id'] = e_rid + + # 2. Prevent "Collision Population" + for k in ['id', 'event_cfg_id', 'account_id', 'event_id']: + if k in values and not isinstance(values[k], str) and values[k] is not None: + del values[k] + + return values enable: Optional[bool] enable_from: Optional[datetime.datetime] @@ -105,6 +129,11 @@ class Event_Cfg_Base(BaseModel): _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'account_id', 'event_id', 'event_registration_cfg' + ] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = True diff --git a/app/models/event_device_models.py b/app/models/event_device_models.py index 5953560..c24b01d 100644 --- a/app/models/event_device_models.py +++ b/app/models/event_device_models.py @@ -148,7 +148,7 @@ class Event_Device_Base(BaseModel): return values # Fields that are part of the model (for reading) but should not be saved to the DB table - fields_to_exclude_from_db: ClassVar[list] = ['event_cfg', 'event_location'] + fields_to_exclude_from_db: ClassVar[list] = ['account_id', 'event_cfg', 'event_location'] class Config: underscore_attrs_are_private = True diff --git a/app/models/event_exhibit_models.py b/app/models/event_exhibit_models.py index 0d5a850..89b3d5e 100644 --- a/app/models/event_exhibit_models.py +++ b/app/models/event_exhibit_models.py @@ -1,6 +1,6 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union +from typing import Dict, List, Optional, Set, Union, ClassVar from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import redis_lookup_id_random @@ -143,6 +143,11 @@ class Event_Exhibit_Base(BaseModel): _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'event_exhibit_tracking_list' + ] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = True diff --git a/app/models/event_exhibit_tracking_models.py b/app/models/event_exhibit_tracking_models.py index 5c3ebe8..38e26be 100644 --- a/app/models/event_exhibit_tracking_models.py +++ b/app/models/event_exhibit_tracking_models.py @@ -1,6 +1,6 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union +from typing import Dict, List, Optional, Set, Union, ClassVar from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import redis_lookup_id_random @@ -215,6 +215,28 @@ class Event_Exhibit_Tracking_Base(BaseModel): _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'account_id', + 'event_badge_pronouns', 'event_badge_pronouns_override', 'event_badge_informal_name', + 'event_badge_title_names', 'event_badge_given_name', 'event_badge_middle_name', + 'event_badge_family_name', 'event_badge_designations', + 'event_badge_professional_title', 'event_badge_professional_title_override', + 'event_badge_full_name', 'event_badge_full_name_override', + 'event_badge_affiliations', 'event_badge_affiliations_override', + 'event_badge_email', 'event_badge_email_override', + 'event_badge_phone', 'event_badge_phone_override', + 'event_badge_address_line_1', 'event_badge_address_line_2', 'event_badge_address_line_3', + 'event_badge_city', 'event_badge_county', 'event_badge_country_subdivision_code', + 'event_badge_state_province', 'event_badge_state_province_abb', 'event_badge_postal_code', + 'event_badge_country_alpha_2_code', 'event_badge_country', + 'event_badge_location', 'event_badge_location_override', + 'event_person_informal_name', 'event_person_given_name', 'event_person_family_name', + 'event_person_full_name', 'event_person_full_name_override', + 'event_person_affiliations', 'event_person_email', 'event_exhibit_name', + 'event_person' + ] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = True diff --git a/app/models/event_file_models.py b/app/models/event_file_models.py index acf8da4..8cc7ca3 100644 --- a/app/models/event_file_models.py +++ b/app/models/event_file_models.py @@ -1,6 +1,6 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union +from typing import Dict, List, Optional, Set, Union, ClassVar from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import get_id_random, redis_lookup_id_random @@ -206,6 +206,22 @@ class Event_File_Base(BaseModel): _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'account_id', 'filename_no_ext', 'filename_w_ext', + 'hosted_file_hash_sha256', 'hosted_file_subdirectory_path', + 'hosted_file_content_type', 'hosted_file_size', + 'event_name', 'event_code', 'event_start_datetime', 'event_end_datetime', + 'event_location_code', 'event_location_name', 'event_presentation_code', + 'event_presentation_type_code', 'event_presentation_name', + 'event_presentation_start_datetime', 'event_presentation_end_datetime', + 'event_presenter_code', 'event_presenter_given_name', 'event_presenter_family_name', + 'event_presenter_full_name', 'event_presenter_email', 'event_session_code', + 'event_session_type_code', 'event_session_name', 'event_session_start_datetime', + 'event_session_end_datetime', 'event_track_code', 'event_track_name', + 'hosted_file' + ] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = False diff --git a/app/models/event_location_models.py b/app/models/event_location_models.py index 7dabfac..372fe6d 100644 --- a/app/models/event_location_models.py +++ b/app/models/event_location_models.py @@ -1,6 +1,6 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union +from typing import Dict, List, Optional, Set, Union, ClassVar from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import redis_lookup_id_random @@ -129,6 +129,16 @@ class Event_Location_Base(BaseModel): return values + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'account_id', + 'location_type', 'file_count', 'internal_use_count', 'event_file_id_li_json', 'file_count_all', + 'event_name', 'event_start_datetime', 'event_end_datetime', + 'event_abstract_list', 'event_device_list', 'event_file_list', + 'event_file_internal_use_list', 'event_presentation_list', + 'event_presenter_list', 'event_session_list', 'event_track_list' + ] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = False diff --git a/app/models/event_models.py b/app/models/event_models.py index 2670557..51fd1cd 100644 --- a/app/models/event_models.py +++ b/app/models/event_models.py @@ -228,6 +228,17 @@ class Event_Base(BaseModel): return str(v) return v + # Fields that are part of the model (for reading) but should not be saved to the DB table. + # These convenience fields and related objects are joined in the view. + fields_to_exclude_from_db: ClassVar[list] = [ + 'file_count', 'internal_use_count', 'event_file_id_li_json', 'file_count_all', + 'address_location', 'contact_1', 'contact_2', 'contact_3', + 'event_abstract_list', 'event_cfg', 'event_device_list', 'event_exhibit_list', + 'event_file_list', 'event_location_list', 'event_person_list', + 'event_presentation_list', 'event_presenter_list', 'event_session_list', + 'event_track_list', 'poc_person' + ] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = True diff --git a/app/models/event_person_models.py b/app/models/event_person_models.py index 52a4737..51c5db5 100644 --- a/app/models/event_person_models.py +++ b/app/models/event_person_models.py @@ -1,7 +1,7 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union -from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator +from typing import Dict, List, Optional, Set, Union, ClassVar +from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import redis_lookup_id_random from app.lib_general import log, logging @@ -22,40 +22,33 @@ class Event_Person_Base(BaseModel): log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) - id_random: Optional[str] = Field( - # **base_fields['event_person_id_random'], - alias = 'event_person_id_random', - ) - id: Optional[int] = Field( - alias = 'event_person_id' - ) + # --- Standardized Vision IDs (Strings) --- + id: Optional[str] = Field(None, **base_fields['event_person_id_random']) + event_person_id: Optional[str] = Field(None, **base_fields['event_person_id_random']) - account_id_random: Optional[str] - account_id: Optional[int] + account_id: Optional[str] = Field(None, **base_fields['account_id_random']) + event_id: Optional[str] = Field(None, **base_fields['event_id_random']) - event_id_random: Optional[str] - event_id: Optional[int] + event_badge_id: Optional[str] = Field(None, **base_fields['event_badge_id_random']) + event_badge_vendor_id: Optional[str] = Field(None, **base_fields['event_badge_id_random']) + event_badge_vip_id: Optional[str] = Field(None, **base_fields['event_badge_id_random']) - event_badge_id_random: Optional[str] # Default attendee badge - event_badge_id: Optional[int] + event_person_profile_id: Optional[str] = Field(None, **base_fields['event_person_profile_id_random']) + event_registration_id: Optional[str] = Field(None, **base_fields['event_registration_id_random']) + person_id: Optional[str] = Field(None, **base_fields['person_id_random']) + user_id: Optional[str] = Field(None, **base_fields['user_id_random']) - event_badge_vendor_id_random: Optional[str] # Additional vendor badge - event_badge_vendor_id: Optional[int] - - event_badge_vip_id_random: Optional[str] # Additional VIP badge - event_badge_vip_id: Optional[int] - - event_person_profile_id_random: Optional[str] - event_person_profile_id: Optional[int] - - event_registration_id_random: Optional[str] - event_registration_id: Optional[int] - - person_id_random: Optional[str] - person_id: Optional[int] - - user_id_random: Optional[str] - user_id: Optional[int] + # --- Standardized Legacy / Internal IDs (Excluded) --- + id_random: Optional[str] = Field(None, alias='event_person_id_random', exclude=True) + account_id_random: Optional[str] = Field(None, exclude=True) + event_id_random: Optional[str] = Field(None, exclude=True) + event_badge_id_random: Optional[str] = Field(None, exclude=True) + event_badge_vendor_id_random: Optional[str] = Field(None, exclude=True) + event_badge_vip_id_random: Optional[str] = Field(None, exclude=True) + event_person_profile_id_random: Optional[str] = Field(None, exclude=True) + event_registration_id_random: Optional[str] = Field(None, exclude=True) + person_id_random: Optional[str] = Field(None, exclude=True) + user_id_random: Optional[str] = Field(None, exclude=True) external_id: Optional[str] # Generated internally or externally. Needs to be stable. It should not change. external_event_id: Optional[str] # Event ID generated by external system. Needs to be stable. It should not change. @@ -159,81 +152,54 @@ class Event_Person_Base(BaseModel): _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) - #@validator('event_person_id_random', always=True) - def event_person_id_random_copy(cls, v, values, **kwargs): - if values['id_random']: - return values['id_random'] - return None + @root_validator(pre=True) + def map_v3_ids(cls, values): + """ + Vision Transformer: + Map DB keys to clean API keys and strip internal integers. + """ + # 1. Map Random Strings to Clean Names + if rid := values.get('id_random') or values.get('event_person_id_random'): + values['id'] = rid + values['event_person_id'] = rid + + if a_rid := values.get('account_id_random'): values['account_id'] = a_rid + if e_rid := values.get('event_id_random'): values['event_id'] = e_rid + if b_rid := values.get('event_badge_id_random'): values['event_badge_id'] = b_rid + if bv_rid := values.get('event_badge_vendor_id_random'): values['event_badge_vendor_id'] = bv_rid + if bvip_rid := values.get('event_badge_vip_id_random'): values['event_badge_vip_id'] = bvip_rid + if ep_rid := values.get('event_person_profile_id_random'): values['event_person_profile_id'] = ep_rid + if er_rid := values.get('event_registration_id_random'): values['event_registration_id'] = er_rid + if p_rid := values.get('person_id_random'): values['person_id'] = p_rid + if u_rid := values.get('user_id_random'): values['user_id'] = u_rid + + # 2. Prevent "Collision Population" + for k in ['id', 'event_person_id', 'account_id', 'event_id', 'event_badge_id', 'event_badge_vendor_id', 'event_badge_vip_id', 'event_person_profile_id', 'event_registration_id', 'person_id', 'user_id']: + if k in values and not isinstance(values[k], str) and values[k] is not None: + del values[k] + + return values - @validator('id', always=True) - def event_person_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event_person') - return None - - @validator('account_id', always=True) - def account_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('account_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='account') - return None - - @validator('event_id', always=True) - def event_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('event_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event') - return None - - @validator('event_badge_id', always=True) - def event_badge_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('event_badge_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event_badge') - return None - - @validator('event_badge_vendor_id', always=True) - def event_badge_vendor_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('event_badge_vendor_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event_badge') - return None - - @validator('event_badge_vip_id', always=True) - def event_badge_vip_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('event_badge_vip_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event_badge') - return None - - @validator('event_person_profile_id', always=True) - def event_person_profile_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('event_person_profile_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event_person_profile') - return None - - @validator('event_registration_id', always=True) - def event_registration_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('event_registration_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event_registration') - return None - - @validator('person_id', always=True) - def person_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('person_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='person') - return None - - @validator('user_id', always=True) - def user_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('user_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='user') - return None + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'file_count', + 'informal_name', 'given_name', 'middle_name', 'family_name', 'full_name_override', 'full_name', + 'affiliations', 'email', 'website_url', + 'event_badge_informal_name', 'event_badge_given_name', 'event_badge_middle_name', + 'event_badge_family_name', 'event_badge_full_name', 'event_badge_full_name_override', + 'event_badge_affiliations', 'event_badge_email', 'event_badge_city', + 'event_badge_state_province', 'event_badge_country_alpha_2_code', 'event_badge_country', + 'event_person_informal_name', 'event_person_given_name', 'event_person_middle_name', + 'event_person_family_name', 'event_person_name_override', 'event_person_full_name', + 'event_person_affiliations', 'event_person_email', 'event_person_extended_json', + 'person_informal_name', 'person_given_name', 'person_middle_name', 'person_family_name', + 'person_full_name', 'person_full_name_override', 'person_affiliations', 'person_email', + 'user_email', 'user_name', 'user_username', + 'event_badge', 'event_badge_vendor', 'event_badge_vip', 'event_exhibit_list', + 'event_file_list', 'event_location_list', 'event_person_profile', + 'event_presentation_list', 'event_presenter_list', 'event_registration', + 'event_session', 'event_track', 'person', 'user' + ] class Config: underscore_attrs_are_private = True @@ -247,17 +213,17 @@ class Event_Person_New_Base(BaseModel): log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) - id_random: Optional[str] = Field( - **base_fields['event_person_id_random'], - alias = 'event_person_id_random', - ) - id: Optional[int] = Field( - alias = 'event_person_id' - ) - account_id_random: Optional[str] - account_id: Optional[int] - event_id_random: Optional[str] - event_id: Optional[int] + # --- Standardized Vision IDs (Strings) --- + id: Optional[str] = Field(None, **base_fields['event_person_id_random']) + event_person_id: Optional[str] = Field(None, **base_fields['event_person_id_random']) + + account_id: Optional[str] = Field(None, **base_fields['account_id_random']) + event_id: Optional[str] = Field(None, **base_fields['event_id_random']) + + # --- Standardized Legacy / Internal IDs (Excluded) --- + id_random: Optional[str] = Field(None, alias='event_person_id_random', exclude=True) + account_id_random: Optional[str] = Field(None, exclude=True) + event_id_random: Optional[str] = Field(None, exclude=True) extended_json: Optional[Union[Json, None]] @@ -319,32 +285,43 @@ class Event_Person_New_Base(BaseModel): _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) - #@validator('event_person_id_random', always=True) - def event_person_id_random_copy(cls, v, values, **kwargs): - if values['id_random']: - return values['id_random'] - return None + @root_validator(pre=True) + def map_v3_ids(cls, values): + """ + Vision Transformer: + Map DB keys to clean API keys and strip internal integers. + """ + # 1. Map Random Strings to Clean Names + if rid := values.get('id_random') or values.get('event_person_id_random'): + values['id'] = rid + values['event_person_id'] = rid + + if a_rid := values.get('account_id_random'): + values['account_id'] = a_rid + if e_rid := values.get('event_id_random'): + values['event_id'] = e_rid + + # 2. Prevent "Collision Population" + for k in ['id', 'event_person_id', 'account_id', 'event_id']: + if k in values and not isinstance(values[k], str) and values[k] is not None: + del values[k] + + return values - @validator('id', always=True) - def event_person_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event_person') - return None - - @validator('account_id', always=True) - def account_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('account_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='account') - return None - - @validator('event_id', always=True) - def event_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('event_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event') - return None + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'informal_name', 'given_name', 'middle_name', 'family_name', 'full_name', + 'full_name_override', 'affiliations', 'email', 'website_url', 'state_province_name', + 'event_badge_informal_name', 'event_badge_given_name', 'event_badge_middle_name', + 'event_badge_family_name', 'event_badge_full_name', 'event_badge_full_name_override', + 'event_badge_affiliations', 'event_badge_email', 'event_badge_city', + 'event_badge_state_province', 'event_badge_country_alpha_2_code', 'event_badge_country', + 'event_person_informal_name', 'event_person_given_name', 'event_person_middle_name', + 'event_person_family_name', 'event_person_name_override', 'event_person_full_name', + 'event_person_affiliations', 'event_person_email', + 'person_given_name', 'person_middle_name', 'person_family_name', + 'person_full_name', 'person_full_name_override', 'new_password' + ] class Config: underscore_attrs_are_private = True diff --git a/app/models/event_person_profile_models.py b/app/models/event_person_profile_models.py index f6937c8..adb4f94 100644 --- a/app/models/event_person_profile_models.py +++ b/app/models/event_person_profile_models.py @@ -1,7 +1,7 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union -from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator +from typing import Dict, List, Optional, Set, Union, ClassVar +from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import redis_lookup_id_random from app.lib_general import log, logging @@ -17,28 +17,23 @@ class Event_Person_Profile_Base(BaseModel): log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) - id_random: Optional[str] = Field( - **base_fields['event_person_profile_id_random'], - alias = 'event_person_profile_id_random', - ) - id: Optional[int] = Field( - alias = 'event_person_profile_id' - ) + # --- Standardized Vision IDs (Strings) --- + id: Optional[str] = Field(None, **base_fields['event_person_profile_id_random']) + event_person_profile_id: Optional[str] = Field(None, **base_fields['event_person_profile_id_random']) - account_id_random: Optional[str] - account_id: Optional[int] + account_id: Optional[str] = Field(None, **base_fields['account_id_random']) + contact_id: Optional[str] = Field(None, **base_fields['contact_id_random']) + event_id: Optional[str] = Field(None, **base_fields['event_id_random']) + event_person_id: Optional[str] = Field(None, **base_fields['event_person_id_random']) + organization_id: Optional[str] = Field(None, **base_fields['organization_id_random']) - contact_id_random: Optional[str] - contact_id: Optional[int] - - event_id_random: Optional[str] # Only in view - event_id: Optional[int] # Only in view - - event_person_id_random: Optional[str] # Only in view - event_person_id: Optional[int] # Only in view - - organization_id_random: Optional[str] - organization_id: Optional[int] + # --- Standardized Legacy / Internal IDs (Excluded) --- + id_random: Optional[str] = Field(None, alias='event_person_profile_id_random', exclude=True) + account_id_random: Optional[str] = Field(None, exclude=True) + contact_id_random: Optional[str] = Field(None, exclude=True) + event_id_random: Optional[str] = Field(None, exclude=True) + event_person_id_random: Optional[str] = Field(None, exclude=True) + organization_id_random: Optional[str] = Field(None, exclude=True) pronouns: Optional[str] # Preferred pronouns informal_name: Optional[str] @@ -65,21 +60,18 @@ class Event_Person_Profile_Base(BaseModel): email: Optional[str] website_url: Optional[str] - thumbnail_hosted_file_id: Optional[int] - thumbnail_hosted_file_id_random: Optional[str] + thumbnail_hosted_file_id: Optional[str] = Field(None, **base_fields['hosted_file_id_random']) thumbnail_path: Optional[str] thumbnail_bg_color: Optional[str] # photo_path: Optional[str] # photo_bg_color: Optional[str] - picture_hosted_file_id: Optional[int] - picture_hosted_file_id_random: Optional[str] + picture_hosted_file_id: Optional[str] = Field(None, **base_fields['hosted_file_id_random']) picture_path: Optional[str] picture_bg_color: Optional[str] - about_hosted_file_id: Optional[int] - about_hosted_file_id_random: Optional[str] + about_hosted_file_id: Optional[str] = Field(None, **base_fields['hosted_file_id_random']) about_path: Optional[str] email_allowed: Optional[bool] @@ -110,66 +102,37 @@ class Event_Person_Profile_Base(BaseModel): _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) - #@validator('event_person_profile_id_random', always=True) - def event_person_profile_id_random_copy(cls, v, values, **kwargs): - if values['id_random']: - return values['id_random'] - return None + @root_validator(pre=True) + def map_v3_ids(cls, values): + """ + Vision Transformer: + Map DB keys to clean API keys and strip internal integers. + """ + # 1. Map Random Strings to Clean Names + if rid := values.get('id_random') or values.get('event_person_profile_id_random'): + values['id'] = rid + values['event_person_profile_id'] = rid + + if a_rid := values.get('account_id_random'): values['account_id'] = a_rid + if c_rid := values.get('contact_id_random'): values['contact_id'] = c_rid + if e_rid := values.get('event_id_random'): values['event_id'] = e_rid + if ep_rid := values.get('event_person_id_random'): values['event_person_id'] = ep_rid + if o_rid := values.get('organization_id_random'): values['organization_id'] = o_rid + + # 2. Prevent "Collision Population" + for k in ['id', 'event_person_profile_id', 'account_id', 'contact_id', 'event_id', 'event_person_id', 'organization_id']: + if k in values and not isinstance(values[k], str) and values[k] is not None: + del values[k] + + return values - @validator('id', always=True) - def event_person_profile_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event_person_profile') - return None - - @validator('account_id', always=True) - def account_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('account_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='account') - return None - - @validator('contact_id', always=True) - def contact_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('contact_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='contact') - return None - - @validator('organization_id', always=True) - def organization_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('organization_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='organization') - return None - - @validator('thumbnail_hosted_file_id', always=True) - def thumbnail_hosted_file_id_lookup(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) - - if values.get('thumbnail_hosted_file_id_random', None): - return redis_lookup_id_random(record_id_random=values['thumbnail_hosted_file_id_random'], table_name='thumbnail_hosted_file') - return None - - @validator('picture_hosted_file_id', always=True) - def picture_hosted_file_id_lookup(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) - - if values.get('picture_hosted_file_id_random', None): - return redis_lookup_id_random(record_id_random=values['picture_hosted_file_id_random'], table_name='picture_hosted_file') - return None - - @validator('about_hosted_file_id', always=True) - def about_hosted_file_id_lookup(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) - - if values.get('about_hosted_file_id_random', None): - return redis_lookup_id_random(record_id_random=values['about_hosted_file_id_random'], table_name='about_hosted_file') - return None + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'account_id', 'event_id', 'event_person_id', + 'full_name', 'full_name_override', 'display_name', + 'thumbnail_path', 'picture_path', 'about_path', + 'contact', 'event_cfg', 'organization' + ] class Config: underscore_attrs_are_private = True diff --git a/app/models/event_presentation_models.py b/app/models/event_presentation_models.py index 83d3239..691264b 100644 --- a/app/models/event_presentation_models.py +++ b/app/models/event_presentation_models.py @@ -1,6 +1,6 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union +from typing import Dict, List, Optional, Set, Union, ClassVar from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import redis_lookup_id_random @@ -22,12 +22,22 @@ class Event_Presentation_Base(BaseModel): id: Optional[str] = Field(None, **base_fields['event_presentation_id_random']) event_presentation_id: Optional[str] = Field(None, **base_fields['event_presentation_id_random']) + account_id: Optional[str] = Field(None, **base_fields['account_id_random']) event_id: Optional[str] = Field(None, **base_fields['event_id_random']) event_abstract_id: Optional[str] = Field(None, **base_fields['event_abstract_id_random']) event_location_id: Optional[str] = Field(None, **base_fields['event_location_id_random']) event_session_id: Optional[str] = Field(None, **base_fields['event_session_id_random']) event_track_id: Optional[str] = Field(None, **base_fields['event_track_id_random']) + # --- Standardized Legacy / Internal IDs (Excluded) --- + id_random: Optional[str] = Field(None, alias='event_presentation_id_random', exclude=True) + account_id_random: Optional[str] = Field(None, exclude=True) + event_id_random: Optional[str] = Field(None, exclude=True) + event_abstract_id_random: Optional[str] = Field(None, exclude=True) + event_location_id_random: Optional[str] = Field(None, exclude=True) + event_session_id_random: Optional[str] = Field(None, exclude=True) + event_track_id_random: Optional[str] = Field(None, exclude=True) + external_id: Optional[str] = Field( # alias = 'event_presentation_external_id' ) @@ -109,6 +119,8 @@ class Event_Presentation_Base(BaseModel): values['id'] = rid values['event_presentation_id'] = rid + if a_rid := values.get('account_id_random'): + values['account_id'] = a_rid if e_rid := values.get('event_id_random'): values['event_id'] = e_rid if ea_rid := values.get('event_abstract_id_random'): @@ -121,12 +133,22 @@ class Event_Presentation_Base(BaseModel): values['event_track_id'] = et_rid # 2. Prevent "Collision Population" - for k in ['id', 'event_presentation_id', 'event_id', 'event_abstract_id', 'event_location_id', 'event_session_id', 'event_track_id']: + for k in ['id', 'event_presentation_id', 'account_id', 'event_id', 'event_abstract_id', 'event_location_id', 'event_session_id', 'event_track_id']: if k in values and not isinstance(values[k], str) and values[k] is not None: del values[k] return values + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'account_id', 'file_count', + 'event_name', 'event_start_datetime', 'event_end_datetime', 'event_location_name', + 'event_session_type_code', 'event_session_name', 'event_session_start_datetime', + 'event_session_end_datetime', 'event_track_name', + 'poc_event_person', 'poc_person', 'event_abstract_list', 'event_file_list', + 'event_presenter_list', 'event_session' + ] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = False diff --git a/app/models/event_presenter_models.py b/app/models/event_presenter_models.py index b9e6dc8..bc24357 100644 --- a/app/models/event_presenter_models.py +++ b/app/models/event_presenter_models.py @@ -1,7 +1,7 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union -from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator +from typing import Dict, List, Optional, Set, Union, ClassVar +from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import redis_lookup_id_random from app.lib_general import log, logging @@ -19,45 +19,32 @@ class Event_Presenter_Base(BaseModel): log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) - id_random: Optional[str] = Field( - # **base_fields['event_presenter_id_random'], - alias = 'event_presenter_id_random', - ) - id: Optional[int] = Field( - alias = 'event_presenter_id' - ) + # --- Standardized Vision IDs (Strings) --- + id: Optional[str] = Field(None, **base_fields['event_presenter_id_random']) + event_presenter_id: Optional[str] = Field(None, **base_fields['event_presenter_id_random']) - account_id_random: Optional[str] - account_id: Optional[int] + account_id: Optional[str] = Field(None, **base_fields['account_id_random']) + event_id: Optional[str] = Field(None, **base_fields['event_id_random']) + event_person_id: Optional[str] = Field(None, **base_fields['event_person_id_random']) + event_presentation_id: Optional[str] = Field(None, **base_fields['event_presentation_id_random']) + event_session_id: Optional[str] = Field(None, **base_fields['event_session_id_random']) + event_track_id: Optional[str] = Field(None, **base_fields['event_track_id_random']) + person_id: Optional[str] = Field(None, **base_fields['person_id_random']) + + # --- Standardized Legacy / Internal IDs (Excluded) --- + id_random: Optional[str] = Field(None, alias='event_presenter_id_random', exclude=True) + account_id_random: Optional[str] = Field(None, exclude=True) + event_id_random: Optional[str] = Field(None, exclude=True) + event_person_id_random: Optional[str] = Field(None, exclude=True) + event_presentation_id_random: Optional[str] = Field(None, exclude=True) + event_session_id_random: Optional[str] = Field(None, exclude=True) + event_track_id_random: Optional[str] = Field(None, exclude=True) + person_id_random: Optional[str] = Field(None, exclude=True) external_id: Optional[str] code: Optional[str] - event_id_random: Optional[str] - event_id: Optional[int] - - # event_abstract_id_random: Optional[str] - # event_abstract_id: Optional[int] - - event_location_id_random: Optional[str] - event_location_id: Optional[int] - - event_person_id_random: Optional[str] - event_person_id: Optional[int] - - event_presentation_id_random: Optional[str] - event_presentation_id: Optional[int] - - event_session_id_random: Optional[str] - event_session_id: Optional[int] - - event_track_id_random: Optional[str] - event_track_id: Optional[int] - - person_id_random: Optional[str] - person_id: Optional[int] - for_type: Optional[str] for_id: Optional[int] @@ -193,58 +180,52 @@ class Event_Presenter_Base(BaseModel): _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) - @validator('id', always=True) - def event_presenter_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event_presenter') - return None + @root_validator(pre=True) + def map_v3_ids(cls, values): + """ + Vision Transformer: + Map DB keys to clean API keys and strip internal integers. + """ + # 1. Map Random Strings to Clean Names + if rid := values.get('id_random') or values.get('event_presenter_id_random'): + values['id'] = rid + values['event_presenter_id'] = rid + + if a_rid := values.get('account_id_random'): values['account_id'] = a_rid + if e_rid := values.get('event_id_random'): values['event_id'] = e_rid + if ep_rid := values.get('event_person_id_random'): values['event_person_id'] = ep_rid + if epr_rid := values.get('event_presentation_id_random'): values['event_presentation_id'] = epr_rid + if es_rid := values.get('event_session_id_random'): values['event_session_id'] = es_rid + if et_rid := values.get('event_track_id_random'): values['event_track_id'] = et_rid + if p_rid := values.get('person_id_random'): values['person_id'] = p_rid + + # 2. Prevent "Collision Population" + for k in ['id', 'event_presenter_id', 'account_id', 'event_id', 'event_person_id', 'event_presentation_id', 'event_session_id', 'event_track_id', 'person_id']: + if k in values and not isinstance(values[k], str) and values[k] is not None: + del values[k] + + return values - @validator('account_id', always=True) - def account_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('account_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='account') - return None - - @validator('event_id', always=True) - def event_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('event_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event') - return None - - @validator('event_person_id', always=True) - def event_person_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('event_person_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event_person') - return None - - @validator('event_presentation_id', always=True) - def event_presentation_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('event_presentation_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event_presentation') - return None - - @validator('event_session_id', always=True) - def event_session_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('event_session_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event_session') - return None - - @validator('person_id', always=True) - def person_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('person_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='person') - return None + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'account_id', 'file_count', 'event_file_id_li_json', + 'event_name', 'event_start_datetime', 'event_end_datetime', + 'event_location_code', 'event_location_name', + 'event_presentation_code', 'event_presentation_type_code', 'event_presentation_name', + 'event_presentation_start_datetime', 'event_presentation_end_datetime', + 'event_session_code', 'event_session_type_code', 'event_session_name', + 'event_session_start_datetime', 'event_session_end_datetime', + 'event_track_code', 'event_track_name', + 'person_external_id', 'person_external_sys_id', 'person_given_name', + 'person_family_name', 'person_professional_title', 'person_full_name', + 'person_affiliations', 'person_primary_email', 'person_passcode', + 'event_abstract', 'event_abstract_list', 'event_cfg', 'event_file_list', + 'event_person', 'event_presentation', 'event_session' + ] class Config: underscore_attrs_are_private = True - allow_population_by_field_name = True + allow_population_by_field_name = False fields = base_fields # ### END ### API Event Presenter Models ### Event_Presenter_Base() ### @@ -255,48 +236,28 @@ class Event_Presenter_Out_Base(BaseModel): log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) - id_random: Optional[str] = Field( - **base_fields['event_presenter_id_random'], - alias = 'event_presenter_id_random', - ) - id: Optional[int] = Field( - alias = 'event_presenter_id' - ) + # --- Standardized Vision IDs (Strings) --- + id: Optional[str] = Field(None, **base_fields['event_presenter_id_random']) + event_presenter_id: Optional[str] = Field(None, **base_fields['event_presenter_id_random']) - account_id_random: Optional[str] - account_id: Optional[int] + account_id: Optional[str] = Field(None, **base_fields['account_id_random']) + event_id: Optional[str] = Field(None, **base_fields['event_id_random']) + person_id: Optional[str] = Field(None, **base_fields['person_id_random']) + event_presentation_id: Optional[str] = Field(None, **base_fields['event_presentation_id_random']) + event_session_id: Optional[str] = Field(None, **base_fields['event_session_id_random']) + + # --- Standardized Legacy / Internal IDs (Excluded) --- + id_random: Optional[str] = Field(None, alias='event_presenter_id_random', exclude=True) + account_id_random: Optional[str] = Field(None, exclude=True) + event_id_random: Optional[str] = Field(None, exclude=True) + person_id_random: Optional[str] = Field(None, exclude=True) + event_presentation_id_random: Optional[str] = Field(None, exclude=True) + event_session_id_random: Optional[str] = Field(None, exclude=True) external_id: Optional[str] code: Optional[str] - event_id_random: Optional[str] - event_id: Optional[int] - - # event_abstract_id_random: Optional[str] - # event_abstract_id: Optional[int] - - # event_location_id_random: Optional[str] - # event_location_id: Optional[int] - - # event_person_id_random: Optional[str] - # event_person_id: Optional[int] - - event_presentation_id_random: Optional[str] - event_presentation_id: Optional[int] - - event_session_id_random: Optional[str] - event_session_id: Optional[int] - - # event_track_id_random: Optional[str] - # event_track_id: Optional[int] - - person_id_random: Optional[str] - person_id: Optional[int] - - # for_type: Optional[str] - # for_id: Optional[int] - pronouns: Optional[str] # Preferred pronouns informal_name: Optional[str] # Informal or nick name they commonly go by @@ -311,38 +272,24 @@ class Event_Presenter_Out_Base(BaseModel): professional_title: Optional[str] # Professional title # title: Optional[str] # NOTE: Phasing out! Use *professional_title* instead. - # display_name: Optional[str] # NOTE: This will be changed to full_name_override to match event_badge, event_person_profile, and person - # BEGIN # Auto created name variations full_name: Optional[str] # title_names given_name middle_name family_name designations full_name_override: Optional[str] # Override full_name; Actual name shown for presenter - # degree: Optional[str] # NOTE: Phasing out! Use *designations* instead. - # degrees: Optional[str] # NOTE: Phasing out! Use *designations* instead. - # credentials: Optional[str] # NOTE: Phasing out! Use *designations* instead. - affiliations: Optional[str] # One or more affiliations with organizations, companies, and other groups # affiliation: Optional[str] # NOTE: Phasing out! Use *affiliations* instead. email: Optional[str] website_url: Optional[str] - # phone_li_json: Optional[Union[Json, None]] - # For social media in a JSON object format. The Aether standard field names should be used. Examples: url, url_text, icon, etc. social_li_json: Optional[Union[Json, None]] tagline: Optional[str] biography: Optional[str] - # picture_path: Optional[str] # Start using image_li_json instead - # picture_bg_color: Optional[str] - # For image files only in a JSON object format. The Aether standard field names should be used. Examples: url, url_text, alt_text, width, height, size (in bytes), etc. image_li_json: Optional[Union[Json, None]] # "headshot" is probably the most common - # media_li_json: Optional[Union[Json, None]] - - # role: Optional[str] data_json: Optional[Union[Json, None]] # For key value data. Careful with overwriting existing fields! cfg_json: Optional[Union[Json, None]] # Store per presenter config options like theme, language, etc @@ -356,13 +303,8 @@ class Event_Presenter_Out_Base(BaseModel): comments: Optional[str] enable: Optional[bool] - # enable_from: Optional[datetime.datetime] = None - # enable_to: Optional[datetime.datetime] = None hide: Optional[bool] - # public: Optional[bool] - # public_hide: Optional[bool] - # hide_event_launcher: Optional[bool] priority: Optional[bool] sort: Optional[int] # The presenter number if given @@ -372,24 +314,6 @@ class Event_Presenter_Out_Base(BaseModel): created_on: Optional[datetime.datetime] = None updated_on: Optional[datetime.datetime] = None - # Including convenience data - # This is only for convenience. Probably going to keep unless it causes a problem. - # event_name: Optional[str] - # event_start_datetime: Optional[datetime.datetime] - # event_end_datetime: Optional[datetime.datetime] - # event_location_code: Optional[str] - # event_location_name: Optional[str] - # event_presentation_code: Optional[str] - # event_presentation_type_code: Optional[str] - # event_presentation_name: Optional[str] - # event_presentation_start_datetime: Optional[datetime.datetime] - # event_presentation_end_datetime: Optional[datetime.datetime] - # event_session_code: Optional[str] - # event_session_type_code: Optional[str] - # event_session_name: Optional[str] - # event_session_start_datetime: Optional[datetime.datetime] - # event_session_end_datetime: Optional[datetime.datetime] - person_external_id: Optional[str] person_external_sys_id: Optional[str] person_given_name: Optional[str] @@ -404,50 +328,32 @@ class Event_Presenter_Out_Base(BaseModel): _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) - @validator('id', always=True) - def event_presenter_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event_presenter') - return None - - @validator('event_id', always=True) - def event_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('event_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event') - return None - - # @validator('event_person_id', always=True) - # def event_person_id_lookup(cls, v, values, **kwargs): - # if isinstance(v, int) and v > 0: return v - # elif id_random := values.get('event_person_id_random'): - # return redis_lookup_id_random(record_id_random=id_random, table_name='event_person') - # return None - - @validator('event_presentation_id', always=True) - def event_presentation_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('event_presentation_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event_presentation') - return None - - @validator('event_session_id', always=True) - def event_session_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('event_session_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='event_session') - return None - - @validator('person_id', always=True) - def person_id_lookup(cls, v, values, **kwargs): - if isinstance(v, int) and v > 0: return v - elif id_random := values.get('person_id_random'): - return redis_lookup_id_random(record_id_random=id_random, table_name='person') - return None + @root_validator(pre=True) + def map_v3_ids(cls, values): + """ + Vision Transformer: + Map DB keys to clean API keys and strip internal integers. + """ + # 1. Map Random Strings to Clean Names + if rid := values.get('id_random') or values.get('event_presenter_id_random'): + values['id'] = rid + values['event_presenter_id'] = rid + + if a_rid := values.get('account_id_random'): values['account_id'] = a_rid + if e_rid := values.get('event_id_random'): values['event_id'] = e_rid + if epr_rid := values.get('event_presentation_id_random'): values['event_presentation_id'] = epr_rid + if es_rid := values.get('event_session_id_random'): values['event_session_id'] = es_rid + if p_rid := values.get('person_id_random'): values['person_id'] = p_rid + + # 2. Prevent "Collision Population" + for k in ['id', 'event_presenter_id', 'account_id', 'event_id', 'event_presentation_id', 'event_session_id', 'person_id']: + if k in values and not isinstance(values[k], str) and values[k] is not None: + del values[k] + + return values class Config: underscore_attrs_are_private = True - allow_population_by_field_name = True + allow_population_by_field_name = False fields = base_fields # ### END ### API Event Presenter Models ### Event_Presenter_Base() ### diff --git a/app/models/event_registration_cfg_models.py b/app/models/event_registration_cfg_models.py index 7e4fdc6..8f25c29 100644 --- a/app/models/event_registration_cfg_models.py +++ b/app/models/event_registration_cfg_models.py @@ -1,8 +1,8 @@ from __future__ import annotations import datetime, hashlib, logging, os, pytz, redis, secrets -from typing import Dict, List, Optional, Set, Union -from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator +from typing import Dict, List, Optional, Set, Union, ClassVar +from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import redis_lookup_id_random from app.lib_general import log, logging @@ -14,6 +14,41 @@ class Event_Registration_Cfg_Base(BaseModel): log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) + # --- Standardized Vision IDs (Strings) --- + id: Optional[str] = Field(None, **base_fields['event_registration_cfg_id_random']) + event_registration_cfg_id: Optional[str] = Field(None, **base_fields['event_registration_cfg_id_random']) + + account_id: Optional[str] = Field(None, **base_fields['account_id_random']) + event_id: Optional[str] = Field(None, **base_fields['event_id_random']) + + # --- Standardized Legacy / Internal IDs (Excluded) --- + id_random: Optional[str] = Field(None, alias='event_registration_cfg_id_random', exclude=True) + account_id_random: Optional[str] = Field(None, exclude=True) + event_id_random: Optional[str] = Field(None, exclude=True) + + @root_validator(pre=True) + def map_v3_ids(cls, values): + """ + Vision Transformer: + Map DB keys to clean API keys and strip internal integers. + """ + # 1. Map Random Strings to Clean Names + if rid := values.get('id_random') or values.get('event_registration_cfg_id_random'): + values['id'] = rid + values['event_registration_cfg_id'] = rid + + if a_rid := values.get('account_id_random'): + values['account_id'] = a_rid + if e_rid := values.get('event_id_random'): + values['event_id'] = e_rid + + # 2. Prevent "Collision Population" + for k in ['id', 'event_registration_cfg_id', 'account_id', 'event_id']: + if k in values and not isinstance(values[k], str) and values[k] is not None: + del values[k] + + return values + start_on: Optional[datetime.datetime] end_on: Optional[datetime.datetime] @@ -50,6 +85,9 @@ class Event_Registration_Cfg_Base(BaseModel): _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = True diff --git a/app/models/event_registration_models.py b/app/models/event_registration_models.py index 68955b6..18f45e7 100644 --- a/app/models/event_registration_models.py +++ b/app/models/event_registration_models.py @@ -1,7 +1,7 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union -from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator +from typing import Dict, List, Optional, Set, Union, ClassVar +from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import redis_lookup_id_random from app.lib_general import * @@ -15,24 +15,23 @@ class Event_Registration_Base(BaseModel): log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) - id_random: Optional[str] = Field( - **base_fields['event_registration_id_random'], - alias = 'event_registration_id_random', - ) - id: Optional[int] = Field( - alias = 'event_registration_id' - ) + # --- Standardized Vision IDs (Strings) --- + id: Optional[str] = Field(None, **base_fields['event_registration_id_random']) + event_registration_id: Optional[str] = Field(None, **base_fields['event_registration_id_random']) - account_id_random: Optional[str] - account_id: Optional[int] - event_id_random: Optional[str] - event_id: Optional[int] - organization_id_random: Optional[str] - organization_id: Optional[int] - contact_id_random: Optional[str] - contact_id: Optional[int] - person_id_random: Optional[str] - person_id: Optional[int] + account_id: Optional[str] = Field(None, **base_fields['account_id_random']) + event_id: Optional[str] = Field(None, **base_fields['event_id_random']) + organization_id: Optional[str] = Field(None, **base_fields['organization_id_random']) + contact_id: Optional[str] = Field(None, **base_fields['contact_id_random']) + person_id: Optional[str] = Field(None, **base_fields['person_id_random']) + + # --- Standardized Legacy / Internal IDs (Excluded) --- + id_random: Optional[str] = Field(None, alias='event_registration_id_random', exclude=True) + account_id_random: Optional[str] = Field(None, exclude=True) + event_id_random: Optional[str] = Field(None, exclude=True) + organization_id_random: Optional[str] = Field(None, exclude=True) + contact_id_random: Optional[str] = Field(None, exclude=True) + person_id_random: Optional[str] = Field(None, exclude=True) priority: Optional[bool] sort: Optional[int] @@ -48,69 +47,32 @@ class Event_Registration_Base(BaseModel): _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) - #@validator('event_registration_id_random', always=True) - def event_registration_id_random_copy(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) + @root_validator(pre=True) + def map_v3_ids(cls, values): + """ + Vision Transformer: + Map DB keys to clean API keys and strip internal integers. + """ + # 1. Map Random Strings to Clean Names + if rid := values.get('id_random') or values.get('event_registration_id_random'): + values['id'] = rid + values['event_registration_id'] = rid + + if a_rid := values.get('account_id_random'): values['account_id'] = a_rid + if e_rid := values.get('event_id_random'): values['event_id'] = e_rid + if o_rid := values.get('organization_id_random'): values['organization_id'] = o_rid + if c_rid := values.get('contact_id_random'): values['contact_id'] = c_rid + if p_rid := values.get('person_id_random'): values['person_id'] = p_rid + + # 2. Prevent "Collision Population" + for k in ['id', 'event_registration_id', 'account_id', 'event_id', 'organization_id', 'contact_id', 'person_id']: + if k in values and not isinstance(values[k], str) and values[k] is not None: + del values[k] + + return values - if values['id_random']: - return values['id_random'] - return None - - @validator('id', always=True) - def event_registration_id_lookup(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) - - if values['id_random']: - log.debug(values['id_random']) - return redis_lookup_id_random(record_id_random=values['id_random'], table_name='event_registration') - return None - - @validator('account_id', always=True) - def account_id_lookup(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) - - if values['account_id_random']: - return redis_lookup_id_random(record_id_random=values['account_id_random'], table_name='account') - return None - - @validator('event_id', always=True) - def event_id_lookup(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) - - if values['event_id_random']: - return redis_lookup_id_random(record_id_random=values['event_id_random'], table_name='event') - return None - - @validator('organization_id', always=True) - def organization_id_lookup(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) - - if values['organization_id_random']: - return redis_lookup_id_random(record_id_random=values['organization_id_random'], table_name='organization') - return None - - @validator('contact_id', always=True) - def contact_id_lookup(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) - - if values['contact_id_random']: - return redis_lookup_id_random(record_id_random=values['contact_id_random'], table_name='contact') - return None - - @validator('person_id', always=True) - def person_id_lookup(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) - - if values['person_id_random']: - return redis_lookup_id_random(record_id_random=values['person_id_random'], table_name='person') - return None + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = ['cfg', 'event_person_list'] class Config: underscore_attrs_are_private = True diff --git a/app/models/event_session_models.py b/app/models/event_session_models.py index b4b151c..c1c5830 100644 --- a/app/models/event_session_models.py +++ b/app/models/event_session_models.py @@ -216,6 +216,7 @@ class Event_Session_Base(BaseModel): # Fields that are part of the model (for reading) but should not be saved to the DB table fields_to_exclude_from_db: ClassVar[list] = [ + 'account_id', 'file_count', 'internal_use_count', 'event_file_id_li_json', 'file_count_all', 'event_name', 'event_start_datetime', 'event_end_datetime', 'event_location_name', 'event_track_name', diff --git a/app/models/event_track_models.py b/app/models/event_track_models.py index 62ecbdd..a264d8d 100644 --- a/app/models/event_track_models.py +++ b/app/models/event_track_models.py @@ -1,7 +1,7 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union -from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator +from typing import Dict, List, Optional, Set, Union, ClassVar +from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import redis_lookup_id_random from app.lib_general import log, logging @@ -15,17 +15,19 @@ class Event_Track_Base(BaseModel): log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) - id_random: Optional[str] = Field( - **base_fields['event_track_id_random'], - alias = 'event_track_id_random', - ) - id: Optional[int] = Field( - alias = 'event_track_id' - ) - event_id_random: Optional[str] - event_id: Optional[int] - event_location_id_random: Optional[str] # Can a location be assigned to one track? - event_location_id: Optional[int] # Can a location be assigned to one track? + # --- Standardized Vision IDs (Strings) --- + id: Optional[str] = Field(None, **base_fields['event_track_id_random']) + event_track_id: Optional[str] = Field(None, **base_fields['event_track_id_random']) + + account_id: Optional[str] = Field(None, **base_fields['account_id_random']) + event_id: Optional[str] = Field(None, **base_fields['event_id_random']) + event_location_id: Optional[str] = Field(None, **base_fields['event_location_id_random']) + + # --- Standardized Legacy / Internal IDs (Excluded) --- + id_random: Optional[str] = Field(None, alias='event_track_id_random', exclude=True) + account_id_random: Optional[str] = Field(None, exclude=True) + event_id_random: Optional[str] = Field(None, exclude=True) + event_location_id_random: Optional[str] = Field(None, exclude=True) lu_track_type_id: Optional[int] track_type_code: Optional[str] @@ -54,6 +56,11 @@ class Event_Track_Base(BaseModel): created_on: Optional[datetime.datetime] = None updated_on: Optional[datetime.datetime] = None + # Including convenience data + event_name: Optional[str] + event_start_datetime: Optional[datetime.datetime] + event_end_datetime: Optional[datetime.datetime] + # Including other related objects #event: Optional[Event_Base] event_abstract_list: Optional[list] # Optional[Event_Abstract_Base] @@ -66,45 +73,41 @@ class Event_Track_Base(BaseModel): _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) - #@validator('event_track_id_random', always=True) - def event_track_id_random_copy(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) + @root_validator(pre=True) + def map_v3_ids(cls, values): + """ + Vision Transformer: + Map DB keys to clean API keys and strip internal integers. + """ + # 1. Map Random Strings to Clean Names + if rid := values.get('id_random') or values.get('event_track_id_random'): + values['id'] = rid + values['event_track_id'] = rid + + if a_rid := values.get('account_id_random'): + values['account_id'] = a_rid + if e_rid := values.get('event_id_random'): + values['event_id'] = e_rid + if el_rid := values.get('event_location_id_random'): + values['event_location_id'] = el_rid + + # 2. Prevent "Collision Population" + for k in ['id', 'event_track_id', 'account_id', 'event_id', 'event_location_id']: + if k in values and not isinstance(values[k], str) and values[k] is not None: + del values[k] + + return values - if values['id_random']: - return values['id_random'] - return None - - @validator('id', always=True) - def event_track_id_lookup(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) - - if values['id_random']: - log.debug(values['id_random']) - return redis_lookup_id_random(record_id_random=values['id_random'], table_name='event_track') - return None - - @validator('event_id', always=True) - def event_id_lookup(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) - - if values['event_id_random']: - return redis_lookup_id_random(record_id_random=values['event_id_random'], table_name='event') - return None - - @validator('event_location_id', always=True) - def event_location_id_lookup(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) - - if values['event_location_id_random']: - return redis_lookup_id_random(record_id_random=values['event_location_id_random'], table_name='event_location') - return None + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'account_id', 'track_type', + 'event_name', 'event_start_datetime', 'event_end_datetime', + 'event_abstract_list', 'event_device_list', 'event_file_list', + 'event_presentation_list', 'event_presenter_list', 'event_session_list', 'event_track_list' + ] class Config: underscore_attrs_are_private = True - allow_population_by_field_name = True + allow_population_by_field_name = False fields = base_fields # ### END ### API Event Track Models ### Event_Track_Base() ### diff --git a/app/models/organization_models.py b/app/models/organization_models.py index 1834e47..79385b7 100644 --- a/app/models/organization_models.py +++ b/app/models/organization_models.py @@ -1,6 +1,6 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union +from typing import Dict, List, Optional, Set, Union, ClassVar from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import redis_lookup_id_random @@ -86,6 +86,11 @@ class Organization_Base(BaseModel): return values + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'contact' + ] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = False diff --git a/app/models/person_models.py b/app/models/person_models.py index 5dcc912..3217daf 100644 --- a/app/models/person_models.py +++ b/app/models/person_models.py @@ -1,6 +1,6 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union +from typing import Dict, List, Optional, Set, Union, ClassVar from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import redis_lookup_id_random @@ -184,6 +184,19 @@ class Person_Base(BaseModel): return True return v + # Fields that are part of the model (for reading) but should not be saved to the DB table + fields_to_exclude_from_db: ClassVar[list] = [ + 'membership_person_id', 'first_last_name', 'first_middle_last_name', + 'last_first_name', 'last_first_middle_name', 'informal_full_name', + 'professional_full_name', 'lu_gender_name', 'email', 'cc_email', + 'username', 'user_name', 'user_email', 'user_allow_auth_key', + 'user_super', 'user_manager', 'user_administrator', 'user_public', + 'event_list', 'hosted_file_list', 'journal_list', 'contact', + 'membership_person', 'membership_group_list', 'membership_type_list', + 'orders_info', 'order_list', 'order_cart', 'order_cart_v3', + 'organization', 'post_list', 'user' + ] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = False