From fced4d5756ae5d9324e49db8ddd6199899163caf Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Thu, 5 May 2022 22:31:44 +0200 Subject: [PATCH] More docs in webmodel --- paramecio2/libraries/db/webmodel.py | 223 +++++++++++++++++++++++++++- 1 file changed, 220 insertions(+), 3 deletions(-) diff --git a/paramecio2/libraries/db/webmodel.py b/paramecio2/libraries/db/webmodel.py index da2f030..e71b302 100644 --- a/paramecio2/libraries/db/webmodel.py +++ b/paramecio2/libraries/db/webmodel.py @@ -342,8 +342,16 @@ class WebModel: related_models_deleted (list): Internal variable used for delete tables from db. required_save (str): Internal variable used for required fields defined in self.fields primary_key (str): Default name of primary key field - yes_reset_conditions (bool): - + yes_reset_conditions (bool): If True, methods how select and update reset self.conditions. If False, self.conditions is used in next select and update executions. + updated (bool): True if the model is used for update, False if the model is used for insert or other operations. + valid_fields (list): List with the fields validated for insert or update + last_id (int): The id of last inserted row. + distinct (str): Add DISTINCT keyword to self.select method. + post (dict): A simple dictionary where post values are saved for use of fields classes + files_delete (dict): A simple dictionary that save the fields that have files related. If i delete the row in database i need delete the files related + sql_class (SqlClass): A sql_class used for connect to db. + show_formatted (bool): If True, by default all fields are showed with formatted value using show_formatted method of PhangoField classes and children in select method. If False, raw value is showed. + enctype (bool): If True, forms generated using this model are prepared for enctype=multipart/form-data A.K.A. upload files. """ self.cached=WebModel.global_cached @@ -453,7 +461,11 @@ class WebModel: # A method for add the connection def conn(self, sqlclass): + """ Method for get the SqlClass object and prepare sql variables + Args: + sqlclass (SqlClass): A SqlClass object that present the db connection + """ self.sqlclass=sqlclass # Reset conditions @@ -469,6 +481,11 @@ class WebModel: # A method for change the name of table def change_name(self, name): + """ A method for change the name of table + + Args; + name (str): The new name of table + """ self.name=name @@ -477,6 +494,7 @@ class WebModel: # A method where create the new fields of this model def create_fields(self): + """Dummy method for use in children classes for add fields""" #print([i for i in dir(self.__class__) if i[:1] != '_']) #print(dir(self)) @@ -486,6 +504,14 @@ class WebModel: # A method for register the fields def register(self, field_model, required=False): + """A method for register the fields in model class + + With this method, your register your fields in the model, inside self.fields attribute. Fields are used for build the query for get the data from the sql table. + + Args: + field_model (PhangoField): PhangoField object for add to model + required (bool): If True, the field is required when you insert or update a item row in table model. If False, the field is not required. If field is not required and checking fail, the model update/insert ignore it. + """ #self.fields_required[field_model]=field_model.required @@ -527,6 +553,13 @@ class WebModel: # Method for make queries def query(self, str_query, args=[], connection_id='default'): + """Method for make typical sql query to db + + Args: + str_query (str): The str query. Use the typical format of sql python drivers, example: select * from my_table WHERE id=%s. + args (list): The arguments to substitute %s characters of the strings. The list must sequential with %s characters in the string. + connection_id (str): The connection data used for this connection, by default is "default". + """ self.connect_to_db() return self.sqlclass.query(str_query, args, connection_id) @@ -534,6 +567,8 @@ class WebModel: # Method for clean fields def clean_fields(self): + """Method for delete fields from self.fields dict""" + clean=self.fields_to_clean for field in self.fields_to_clean: del self.fields[field] @@ -542,6 +577,14 @@ class WebModel: # External agent define if the update is in code or from external source, how a form. def insert(self, dict_values, external_agent=True): + """Insert method, for insert a row in database using a dictionary + + This method is a shortcut for typical sql insert sentence. + + Args: + dict_values (dict): A dict with the name of the fields how defined in PhangoField for the keys, and values for the values designed for every field. + external_agent (bool): External agent define if the update is in code or from external source, how a form. + """ self.clean_fields() @@ -598,6 +641,15 @@ class WebModel: # Update method. For update one or many rows. def update(self, dict_values, external_agent=True): + """Upate method, for update a row in database using a dictionary + + This method is a shortcut for typical sql update sentence. + + Args: + dict_values (dict): A dict with the name of the fields how defined in PhangoField for the keys, and values for the values designed for every field. + external_agent (bool): External agent define if the update is in code or from external source, how a form. + """ + self.clean_fields() @@ -672,7 +724,7 @@ class WebModel: """ def reset_conditions(self): - + """Method for reset self.conditions to default values""" self.conditions=["WHERE 1=1", []] self.limit='' @@ -680,6 +732,18 @@ class WebModel: #Type assoc can be assoc for return dictionaries def select(self, arr_select=[], raw_query=False): + """A method for select fields from a table in db. Support for foreignkeys. + + This method is a shortcut for typical sql select sentence. You can select multiple tables using ForeignKeyField class. + + Args: + arr_select (dict): A list with the name of the fields how defined in PhangoField. + raw_query (bool): If True, if foreignkeyfields exists, are not selected. If False, foreignkeyfields are selected too if foreignkeyfield are in arr_select. + + Returns: + Return cursor db for get data using loops or other if operation is successful, if not, return False. + + """ self.clean_fields() @@ -795,14 +859,29 @@ class WebModel: # Show results in a dictionary def fetch(self, cursor): + """ Simple method for get a row from db using cursor + + Args: + cursor (Db cursor): A typical db cursor of python sql interface standard. + + Returns: + dict: Return a dictionary with the row selected. + + """ return cursor.fetchone() def insert_id(self): + """Method for get the id from last row inserted in table""" return self.last_id def element_exists(self, id): + """Check if exist row with id in db + + Args: + id (int): The id of the row to search. + """ self.conditions=['WHERE `'+self.name_field_id+'`=%s', [id]] @@ -820,6 +899,15 @@ class WebModel: pass def select_a_row(self, id, fields_selected=[], raw_query=0): + """Shortcut for get a simple row from a query + + Args: + fields_selected (dict): A list with the name of the fields how defined in PhangoField. + raw_query (bool): If True, if foreignkeyfields exists, are not selected. If False, foreignkeyfields are selected too if foreignkeyfield are in arr_select. + + Returns: + dict: Returns dict with the row values. + """ self.conditions=['WHERE `'+self.name+'`.`'+self.name_field_id+'`=%s', [id]] @@ -841,6 +929,15 @@ class WebModel: return row def select_a_row_where(self, fields_selected=[], raw_query=0, begin=0): + """Shortcut for get a simple row from a query using self.conditions + + Args: + fields_selected (dict): A list with the name of the fields how defined in PhangoField. + raw_query (bool): If True, if foreignkeyfields exists, are not selected. If False, foreignkeyfields are selected too if foreignkeyfield are in arr_select. + + Returns: + dict: Returns dict with the row values. + """ self.limit="limit "+str(begin)+", 1" @@ -859,6 +956,16 @@ class WebModel: def select_to_array(self, fields_selected=[], raw_query=0): + """Shortcut for get a a list of rows from select sql query + + Args: + fields_selected (dict): A list with the name of the fields how defined in PhangoField. + raw_query (bool): If True, if foreignkeyfields exists, are not selected. If False, foreignkeyfields are selected too if foreignkeyfield are in arr_select. + + Returns: + dict: Returns dict with the row values. + """ + if len(fields_selected)==0: fields_selected=list(self.fields.keys()) @@ -899,6 +1006,16 @@ class WebModel: def select_to_dict(self, fields_selected=[], raw_query=0, integer=True): + """Shortcut for get a dict of rows from select sql query + + Args: + fields_selected (dict): A list with the name of the fields how defined in PhangoField. + raw_query (bool): If True, if foreignkeyfields exists, are not selected. If False, foreignkeyfields are selected too if foreignkeyfield are in arr_select. + + Returns: + dict: Returns dict with the row values. + """ + if integer: def check_index(index): return index @@ -944,6 +1061,16 @@ class WebModel: # A method por count num rows affected for sql conditions def select_count(self, field_to_count='id', raw_query=True): + """Method for get a typical sql count using conditions + + Args: + Args: + fields_selected (dict): A list with the name of the fields how defined in PhangoField. + raw_query (bool): If True, if foreignkeyfields exists, are not selected. If False, foreignkeyfields are selected too if foreignkeyfield are in arr_select. + + Returns: + int: Returns the number of elements selected. + """ # Connect to db @@ -990,6 +1117,11 @@ class WebModel: # A method for delete rows using sql conditions def delete(self): + """Method for delete a series of rows using conditions + + Returns: + bool: If delete is successfully, return True, if not, return False. + """ #self.connect_to_db() @@ -1012,6 +1144,15 @@ class WebModel: return False def set_conditions(self, sql_text, values:list) -> object: + """Method for set conditions for a typical sql query + + Args: + sql_text (str): The sql text with the conditions, Example: WHERE id=%s + values (list): A list with values for substitute %s characters for the real values filtered for not allow sql injections. + + Returns: + Return the same object with self.conditions modified. + """ self.conditions=[sql_text, values] @@ -1019,6 +1160,15 @@ class WebModel: @staticmethod def check_in_list(in_list): + """Method for convert values to int for use in IN (1,2,3) sql sentences. + + Args: + in_list (list): List with numbers items. + + Returns: + string with (1,2,3) sql sentence filtered. + + """ for x in range(0, len(in_list)): try: @@ -1028,6 +1178,15 @@ class WebModel: return '('+', '.join(in_list)+')' def check_in_list_str(self, field, in_list): + """Method for convert values to int for use in IN (value1, value2, value3) sql sentences. + + Args: + field (PhangoField): The PhangoField used for check the values of in_list + in_list (list): List with value items. + + Returns: + string with (value1, value2, value3) sql sentence filtered. + """ for x in range(0, len(in_list)): in_list[x]=str(self.fields[field].check(in_list[x])) @@ -1035,6 +1194,15 @@ class WebModel: return '("'+'", "'.join(in_list)+'")' def set_order(self, order:dict) -> object: + """ Method for set and complete the query with "order by" sentences. + + Args: + order (dict): A dict with a field name how key, and 0 or 1 how values. 0 define order how ASC, 1 define order how DESC. + + Returns: + + Returns the same object for execute a query after set_order declaration. + """ arr_order=[] arr_order.append('ASC') @@ -1053,6 +1221,15 @@ class WebModel: return self def set_limit(self, limit: tuple) -> None: + """ Method for set and complete the query with "limit" sentences. + + Args: + limit (tuple): A tuple with one or two elements. If one element, example (1), the result is "LIMIT first_element", if two elements, example (1,2), the result is "LIMIT first_element, two_element" + + Returns: + + Returns the same object for execute a query after set_order declaration. + """ limit[0]=int(limit[0]) @@ -1068,6 +1245,7 @@ class WebModel: # Method for create sql tables def create_table(self): + """Method for create a table from this model object""" #self.connect_to_db() @@ -1178,6 +1356,12 @@ class WebModel: # Method for drop sql tables and related def drop(self): + """Method for drop a table based in this model + + Returns: + Return True if table was dropped successfully, false if table can't be dropped. + """ + return self.query('DROP TABLE '+self.name, [], self.connection_id) #Return an array with all fields @@ -1195,6 +1379,10 @@ class WebModel: external_agent (bool): If True, the query is considered manipulated by external agent and the checks are stricts, if not, checks are not stricts yes_update (bool): If True, the check need be done for update sql sentence, if False, the check is done for insert sql sentence errors_set (str): If insert value, the errors are set for insert sql statement, if update value, then the errors are set for update sql statement. + + Returns: + Return False if checking is wrong. If not False returns a tuple with fields filtered, original values as values and values filtered how update_values + return (fields, values, update_values) """ fields=[] @@ -1324,6 +1512,7 @@ class WebModel: #Reset the require field in fields def reset_require(self): + """Reset the require attribute in fields""" for k, v in self.fields.items(): @@ -1334,6 +1523,7 @@ class WebModel: #Reload the require field in fields def reload_require(self): + """Reload the require field in fields""" for k,r in self.fields.items(): self.fields[k].required=r @@ -1341,6 +1531,7 @@ class WebModel: #Choose all fields to updated def set_valid_fields(self, fields={}): + """Choose all fields to updated""" if len(fields)==0: fields=self.fields.keys() @@ -1350,6 +1541,7 @@ class WebModel: #Create a form based in table. def create_forms(self, arr_fields=[]): + """Create a form based in table.""" self.forms=OrderedDict() @@ -1367,6 +1559,12 @@ class WebModel: return arr_fields def create_form_after(self, form_after, new_form): + """Create form after other form + + Args: + form_after (str): The name of the form where the new form is located next + new_form (BaseForm): The BaseForm or derivated class used for create the new form. + """ new_dict=OrderedDict() @@ -1378,6 +1576,11 @@ class WebModel: self.forms=new_dict def show_errors(self): + """Get all errors of model last operation. + + Returns: + str: A string with all errors. + """ arr_error=[] error_txt='' @@ -1398,6 +1601,11 @@ class WebModel: return error_txt def collect_errors(self): + """Get all errors and save in dictionary + + Returns: + dict: Return a dict where the key is the field where the error exists and value is the error text. + """ arr_error= {} error_txt='' @@ -1415,12 +1623,15 @@ class WebModel: return arr_error def safe_query(self): + """Method for reset require for fields. + With this method you can make queries without real checks, except mysql injection safe variables.""" self.create_forms() self.reset_require() def close(self): + """Method for close sqlclass db connection""" self.sqlclass.close() @@ -1438,6 +1649,7 @@ class WebModel: #del sqlclass.connection[key] @staticmethod def escape_sql(value): + """Manual escape for sql, you shouldn't use it""" value=str(value) @@ -1451,6 +1663,11 @@ class WebModel: # Set post values from a post array def set_post_values(self, post): + """Prepare a dict with values using fields keys how base + + Returns: + dict: Return a dict with values without checking anything. + """ for k in self.fields.keys():