Example #1
0
    def get_column(self, column):
        if "." in column.model_name:
            column_path = column.model_name.split(".")

            # get the column we are getting
            column_name = column_path[-1]

            # the path to the column
            column_path = column_path[:-1]
            curmodel = self.model
            for column in column_path:
                curmodel = helpme.get_related_model(curmodel, column)
            model_column = getattr(curmodel, column_name)
        else:
            model_column = getattr(self.model, column.model_name)

        return model_column
Example #2
0
    def get_column(self, column):
        if "." in column.model_name:
            column_path = column.model_name.split(".")

            # get the column we are getting
            column_name = column_path[-1]

            # the path to the column
            column_path = column_path[:-1]
            curmodel = self.model
            for column in column_path:
                curmodel = helpme.get_related_model(curmodel, column)
            model_column = getattr(curmodel, column_name)
        else:
            model_column = getattr(self.model, column.model_name)

        return model_column
Example #3
0
    def __init__(self, params, model, query, columns, total_recs=0):
        self.params = params
        self.model = model
        self.query = query
        self.data = {}
        self.columns = []
        self.columns_dict = {}
        self.total_recs = total_recs

        for col in columns:
            name, model_name, filter_func = None, None, None

            if isinstance(col, DataColumn):
                d = col
                self.columns.append(d)
            elif isinstance(col, tuple):
                # col is either 1. (name, model_name), 2. (name, filter) or 3. (name, model_name, filter)
                if len(col) == 3:
                    name, model_name, filter_func = col
                elif len(col) == 2:
                    # Work out the second argument. If it is a function then it's type 2, else it is type 1.
                    if callable(col[1]):
                        name, filter_func = col
                        model_name = name
                    else:
                        name, model_name = col
                else:
                    raise ValueError(
                        "Columns must be a tuple of 2 to 3 elements")
                d = DataColumn(name=name,
                               model_name=model_name,
                               filter=filter_func)
                self.columns.append(d)
            else:
                # It's just a string
                name, model_name = col, col
                d = DataColumn(name=name, model_name=model_name, filter=None)
                self.columns.append(d)
            self.columns_dict[d.name] = d

        # get only unique relationships to join
        # fix for when there are multiple columns within the same joined table
        # only eliminates warnings but still...
        seenjoins = []
        seencols = []
        for column in (col for col in self.columns if "." in col.model_name):
            # of of table user model_name can look like family.address.city or more/less dots
            # joincols would be ['family', 'address'] leaving out the actual column, city
            log_debug("column: {}".format(column))
            joincols = column.model_name.split(".")[:-1]
            log_debug("joincols: {}".format(joincols))

            curtable = helpme.get_related_model(self.model,
                                                joincols[0]).__tablename__
            log_debug("curtable: {}, joincols: {}".format(curtable, joincols))
            # join the first column, which is off of our class
            # check if 'family' is joined already
            if joincols[0] not in seencols and curtable not in seenjoins:
                seenjoins.append(curtable)
                log_debug("seenjoins is now: {}".format(seenjoins))
                # append family to seencols so we don't rejoin later
                log_debug("appending {} to seencols".format(joincols[0]))
                seencols.append(joincols[0])
                # outer join family
                log_debug("joincols[0] is {}".format(joincols[0]))
                self.query = self.query.join(joincols[0], isouter=True)
                log_debug("query is now: {}".format(self.query))

            # check if we are doing more than the simple user.famly join (in this example user.family.address)
            if len(joincols) > 1:

                # copy our table to curmodel
                curmodel = self.model
                log_debug("curmodel is now: {}".format(curmodel.__tablename__))

                # we don't want to do this to the last item ([:-1])
                for i, joincol in enumerate(joincols[:-1]):

                    # helper method to get the table for the current related model
                    curmodel = helpme.get_related_model(curmodel, joincol)
                    log_debug("i -> {}, joincol -> {}".format(i, joincol))

                    # we don't want to do this for columns we already did also
                    if joincol not in seencols:
                        log_debug("joincol not in seencols: {}, {}".format(
                            joincol, seencols))
                        seencols.append(joincol)
                    if joincols[i + 1] not in seencols:
                        log_debug(
                            "joincols[i+1] not in seencols: {}, {}".format(
                                joincols[i + 1], seencols))
                        # get the tablename so we can log that we joined with it
                        joinmodel = aliased(
                            helpme.get_related_model(curmodel,
                                                     joincols[i + 1]))
                        if joinmodel.__tablename__ in seenjoins:
                            continue
                        # append to seen joins
                        seenjoins.append(joinmodel.__tablename__)
                        # get the remote table object like User.domus rather than XenDomU like above aliased will pull out
                        joinmodel = getattr(curmodel, joincols[i + 1])
                        log_debug("joinmodel: {}".format(joinmodel))
                        #self.query = self.query.join(getattr(curmodel, joincols[i+1]), isouter=True)
                        self.query = self.query.join(joinmodel, isouter=True)
                        seencols.append(joincols[i + 1])
        log_debug(str(self.query))
Example #4
0
    def __init__(self, params, model, query, columns):
        self.params = params
        self.model = model
        self.query = query
        self.data = {}
        self.columns = []
        self.columns_dict = {}

        for col in columns:
            name, model_name, filter_func = None, None, None

            if isinstance(col, DataColumn):
                d = col
                self.columns.append(d)
            elif isinstance(col, tuple):
                # col is either 1. (name, model_name), 2. (name, filter) or 3. (name, model_name, filter)
                if len(col) == 3:
                    name, model_name, filter_func = col
                elif len(col) == 2:
                    # Work out the second argument. If it is a function then it's type 2, else it is type 1.
                    if callable(col[1]):
                        name, filter_func = col
                        model_name = name
                    else:
                        name, model_name = col
                else:
                    raise ValueError("Columns must be a tuple of 2 to 3 elements")
                d = DataColumn(name=name, model_name=model_name, filter=filter_func)
                self.columns.append(d)
            else:
                # It's just a string
                name, model_name = col, col
                d = DataColumn(name=name, model_name=model_name, filter=None)
                self.columns.append(d)
            self.columns_dict[d.name] = d

        # get only unique relationships to join
        # fix for when there are multiple columns within the same joined table
        # only eliminates warnings but still...
        seenjoins = []
        seencols = []
        for column in (col for col in self.columns if "." in col.model_name):
            # of of table user model_name can look like family.address.city or more/less dots
            # joincols would be ['family', 'address'] leaving out the actual column, city
            log_debug("column: {}".format(column))
            joincols = column.model_name.split(".")[:-1]
            log_debug("joincols: {}".format(joincols))

            curtable = helpme.get_related_model(self.model, joincols[0]).__tablename__
            log_debug("curtable: {}, joincols: {}".format(curtable, joincols))
            # join the first column, which is off of our class
            # check if 'family' is joined already
            if joincols[0] not in seencols and curtable not in seenjoins:
                seenjoins.append(curtable)
                log_debug("seenjoins is now: {}".format(seenjoins))
                # append family to seencols so we don't rejoin later
                log_debug("appending {} to seencols".format(joincols[0]))
                seencols.append(joincols[0])
                # outer join family
                log_debug("joincols[0] is {}".format(joincols[0]))
                self.query = self.query.join(joincols[0], isouter=True)
                log_debug("query is now: {}".format(self.query))

            # check if we are doing more than the simple user.famly join (in this example user.family.address)
            if len(joincols) > 1:

                # copy our table to curmodel
                curmodel = self.model
                log_debug("curmodel is now: {}".format(curmodel.__tablename__))

                # we don't want to do this to the last item ([:-1])
                for i, joincol in enumerate(joincols[:-1]):

                    # helper method to get the table for the current related model
                    curmodel = helpme.get_related_model(curmodel, joincol)
                    log_debug("i -> {}, joincol -> {}".format(i, joincol))

                    # we don't want to do this for columns we already did also
                    if joincol not in seencols:
                        log_debug("joincol not in seencols: {}, {}".format(joincol, seencols))
                        seencols.append(joincol)
                    if joincols[i + 1] not in seencols:
                        log_debug("joincols[i+1] not in seencols: {}, {}".format(joincols[i + 1], seencols))
                        # get the tablename so we can log that we joined with it
                        joinmodel = aliased(helpme.get_related_model(curmodel, joincols[i + 1]))
                        if joinmodel.__tablename__ in seenjoins:
                            continue
                        # append to seen joins
                        seenjoins.append(joinmodel.__tablename__)
                        # get the remote table object like User.domus rather than XenDomU like above aliased will pull out
                        joinmodel = getattr(curmodel, joincols[i + 1])
                        log_debug("joinmodel: {}".format(joinmodel))
                        # self.query = self.query.join(getattr(curmodel, joincols[i+1]), isouter=True)
                        self.query = self.query.join(joinmodel, isouter=True)
                        seencols.append(joincols[i + 1])
        log_debug(str(self.query))