def set_property(self, entity_id=None, relationship_id=None, property_definition_keyname=None, value=None, old_property_id=None, uploaded_file=None, ignore_user=False):
        """
        Saves property value. Creates new one if old_property_id = None. Returns new_property_id.

        """
        if not entity_id:
            return

        if ignore_user == True:
            user_id = None
        else:
            if not self.__user_id:
                return
            user_id = self.__user_id

        # property_definition_keyname is preferred because it could change for existing property
        if old_property_id:
            definition = self.db_get('SELECT pd.keyname, pd.datatype, pd.formula FROM property p, property_definition pd WHERE pd.keyname = p.property_definition_keyname AND p.id = %s LIMIT 1;', old_property_id)
        elif property_definition_keyname:
            definition = self.db_get('SELECT keyname, datatype, formula FROM property_definition WHERE keyname = %s LIMIT 1;', property_definition_keyname)
        else:
            return

        if not definition:
            return

        if old_property_id:
            self.db_execute('UPDATE property SET deleted = NOW(), is_deleted = 1, deleted_by = %s WHERE id = %s;', user_id, old_property_id)
            self.db_execute('UPDATE entity SET changed = NOW(), changed_by = %s WHERE id = %s;', user_id, entity_id)

        if self.db_get("""
            SELECT property.id
            FROM property, property_definition
            WHERE property_definition.keyname = property.property_definition_keyname
            AND property.entity_id = %s
            AND property_definition.dataproperty = 'entu-changed-at'
            LIMIT 1;
        """, entity_id):
            self.db_execute("""
                UPDATE property, property_definition
                SET property.value_display = NOW(), property.value_datetime = NOW(), property.created_by = %s, property.created = NOW()
                WHERE property_definition.keyname = property.property_definition_keyname
                AND property.entity_id = %s
                AND property_definition.dataproperty = 'entu-changed-at';
            """, user_id, entity_id)
        else:
            self.db_execute("""
                INSERT INTO property (property_definition_keyname, entity_id, value_display, value_datetime, created_by, created)
                SELECT keyname, %s, NOW(), NOW(), %s, NOW()
                FROM property_definition
                WHERE dataproperty = 'entu-changed-at'
                AND entity_definition_keyname = (SELECT entity_definition_keyname FROM entity WHERE id = %s LIMIT 1);
            """, entity_id, user_id, entity_id)

        if user_id:
            if self.db_get("""
                SELECT property.id
                FROM property, property_definition
                WHERE property_definition.keyname = property.property_definition_keyname
                AND property.entity_id = %s
                AND property_definition.dataproperty = 'entu-changed-by'
                LIMIT 1;
            """, entity_id):
                self.db_execute("""
                    UPDATE property, property_definition
                    SET property.value_display = NULL, property.value_reference = %s, property.created_by = %s, property.created = NOW()
                    WHERE property_definition.keyname = property.property_definition_keyname
                    AND property.entity_id = %s
                    AND property_definition.dataproperty = 'entu-changed-by';
                """, user_id, user_id, entity_id)
            else:
                self.db_execute("""
                    INSERT INTO property (property_definition_keyname, entity_id, value_reference, created_by, created)
                    SELECT keyname, %s, %s, %s, NOW()
                    FROM property_definition
                    WHERE dataproperty = 'entu-changed-by'
                    AND entity_definition_keyname = (SELECT entity_definition_keyname FROM entity WHERE id = %s LIMIT 1);
                """, entity_id, user_id, user_id, entity_id)

        # If no value, then property is deleted, return
        if not value:
            self.set_mongodb_entity(entity_id)
            return

        value_display = None

        if definition.get('formula') == 1:
            field = 'value_formula'
        elif definition.get('datatype') == 'text':
            field = 'value_text'
            value_display = '%s' % value
            value_display = value_display[:500]
        elif definition.get('datatype') == 'integer':
            field = 'value_integer'
            value_display = '%s' % value
        elif definition.get('datatype') == 'decimal':
            field = 'value_decimal'
            value = value.replace(',', '.')
            value = float(re.sub(r'[^\.0-9:]', '', value))
            value_display = round(value, 2)
        elif definition.get('datatype') == 'date':
            field = 'value_datetime'
            value_display = '%s' % value
        elif definition.get('datatype') == 'datetime':
            field = 'value_datetime'
            value_display = '%s' % value
        elif definition.get('datatype') == 'reference':
            field = 'value_reference'
            r = self.__get_properties(entity_id=value)
            if r:
                value_display = self.__get_properties(entity_id=value)[0]['displayname']
        elif definition.get('datatype') == 'file':
            uploaded_file = value
            field = 'value_file'
            value_display = uploaded_file['filename'][:500]

            if uploaded_file.get('url'):
                value = self.db_execute_lastrowid('INSERT INTO file SET url = %s, filename = %s, created_by = %s, created = NOW();', uploaded_file.get('url', ''), uploaded_file.get('filename', ''), user_id)
            elif uploaded_file.get('s3key'):
                value = self.db_execute_lastrowid('INSERT INTO file SET s3_key = %s, filename = %s, filesize = %s, created_by = %s, created = NOW();', uploaded_file.get('s3key', ''), uploaded_file.get('filename', ''), uploaded_file.get('filesize', ''), user_id)
            else:
                md5 = hashlib.md5(uploaded_file.get('body')).hexdigest()
                directory = os.path.join('/', 'entu', 'files', self.app_settings('database-name'), md5[0])
                filename = os.path.join(directory, md5)

                if not os.path.exists(directory):
                    os.makedirs(directory)
                f = open(filename, 'w')
                f.write(uploaded_file.get('body', ''))
                f.close()

                value = self.db_execute_lastrowid('INSERT INTO file SET md5 = %s, filename = %s, filesize = %s, created_by = %s, created = NOW();', md5, uploaded_file.get('filename', ''), len(uploaded_file.get('body', '')), user_id)

        elif definition.get('datatype') == 'boolean':
            field = 'value_boolean'
            value = 1 if value.lower() == 'true' else 0
            value_display = '%s' % bool(value)
        elif definition.get('datatype') == 'counter':
            field = 'value_counter'
            value_display = '%s' % value
        else:
            field = 'value_string'
            value = value[:500]
            value_display = '%s' % value

        new_property_id = self.db_execute_lastrowid("""
            INSERT INTO property SET
                entity_id = %%s,
                property_definition_keyname = %%s,
                %s = %%s,
                value_display = %%s,
                created = NOW(),
                created_by = %%s;
            """ % field,
            entity_id,
            definition.get('keyname'),
            value,
            value_display,
            user_id
        )

        if definition.get('datatype') == 'file' and uploaded_file.get('s3key'):
            self.db_execute('UPDATE file SET s3_key = CONCAT(s3_key, \'/\', %s) WHERE id = %s LIMIT 1;', new_property_id, value)

        self.db_execute('UPDATE entity SET changed = NOW(), changed_by = %s WHERE id = %s;', user_id, entity_id)

        self.set_mongodb_entity(entity_id)

        return new_property_id
dataset/ETHPy150Open argoroots/Entu/app/main/db.py/Entity.set_property/original