예제 #1
0
    def list(self, qry: Select, limit=None, offset=None, cls=None):
        """
        Performs a query with offset and limit
        Returns a tuple with total record count for the query, and the rows returned by applying offset and limit

        The original query object is left intact

        :param qry: query to use
        :param limit:
        :param offset:
        :param cls: optional Record class to use for rows
        :return: (total_rows, selected_row_list)
        """
        total = 0
        qry = copy.deepcopy(qry)
        sql, values = qry.assemble()
        qry_count = Select(self._dialect).from_(
            {Literal(sql): "qry"}, cols={Literal('COUNT(*)'): 'total'})
        if limit:
            qry.limit(limit, offset)

        with self._db.cursor() as c:
            # count total rows
            sql, _ = qry_count.assemble()
            count_record = c.fetchone(sql, values)
            if count_record:
                total = count_record['total']

        # fetch rows
        rows = self.fetch(qry, cls=cls)
        return total, rows
예제 #2
0
    def table_fields(self, table_name: str, schema=None) -> List[FieldRecord]:
        """
        Get fields of table
        :param table_name:
        :param schema:
        :return:
        """
        if schema is None:
            schema = self.SCHEMA_DEFAULT

        columns = {
            'column_name': 'field',
            'data_type': 'type',
            Literal('false'): 'primary'
        }
        qry = Select(PgSqlDialect()) \
            .from_('columns', columns, schema='information_schema') \
            .where('table_schema', '=', schema) \
            .where('table_name', '=', table_name) \
            .order('ordinal_position')
        idx = self.table_pk(table_name, schema)
        with self._db.cursor() as c:
            fields = c.fetchall(*qry.assemble(),
                                cls=FieldRecord)  # type:list[FieldRecord]
            if idx is not None:
                for f in fields:
                    f.primary = f.field == idx.field
            return fields
예제 #3
0
    def views(self, schema=None) -> List:
        if schema is None:
            schema = self.SCHEMA_DEFAULT

        result = []
        qry = Select(PgSqlDialect()).from_('pg_views', ['viewname']).where(
            'schemaname', '=', schema)
        with self._db.cursor() as c:
            for r in c.fetchall(*qry.assemble()):
                result.append(r['viewname'])
            return result
예제 #4
0
 def view_exists(self, view_name: str, schema=None) -> bool:
     """
     Check if a given view exists
     :param view_name: table name
     :param schema: optional schema
     :return:
     """
     qry = Select(Sqlite3SqlDialect()) \
         .from_('sqlite_master', ['name']) \
         .where('name', '=', view_name) \
         .where('type', '=', 'view')
     with self._db.cursor() as c:
         return len(c.fetchall(*qry.assemble())) > 0
예제 #5
0
 def views(self, schema=None) -> List:
     """
     List all available views on the indicated schema. If no schema is specified, assume public schema
     :param schema: optional schema name
     :return: list of tablenames
     """
     qry = Select(Sqlite3SqlDialect()).from_('sqlite_master').where(
         'type', '=', 'view')
     result = []
     with self._db.cursor() as c:
         for r in c.fetchall(*qry.assemble()):
             if not r['name'].startswith('sqlite_'):
                 result.append(r['name'])
     return result
예제 #6
0
    def fetch_raw(self, qry: Select) -> Optional[list]:
        """
        Fetch a list of rows
        Result is not serialized to record, instead it returns a list of dict-like records directly from the DB driver

        :param qry: query to execute
        :return: list of dict-like result

        Example:
            r.fetch_raw(r.select().where('name', 'like', 'gandalf%'))     # fetch records that match query
        """
        with self._db.cursor() as c:
            sql, values = qry.assemble()
            return c.fetchall(sql, values)
예제 #7
0
    def view_exists(self, view_name: str, schema=None) -> bool:
        """
        Check if a given view exists
        :param view_name: table name
        :param schema: optional schema
        :return:
        """
        if schema is None:
            schema = self.SCHEMA_DEFAULT

        qry = Select(PgSqlDialect()).from_('pg_views', ['viewname']) \
            .where('schemaname', '=', schema) \
            .where('viewname', '=', view_name)
        with self._db.cursor() as c:
            return len(c.fetchall(*qry.assemble())) > 0
예제 #8
0
    def fetch(self, qry: Select, cls=None) -> Optional[list]:
        """
        Fetch a list of rows

        :param qry: query to execute
        :param cls: optional record class (useful for joins that may return different record structures)
        :return: list of record object or empty list

        Example:
            r.fetch(r.select().where('name', 'like', 'gandalf%'))     # fetch records that match query
        """
        with self._db.cursor() as c:
            sql, values = qry.assemble()
            if cls is None:
                cls = self._record
            return c.fetchall(sql, values, cls=cls)
예제 #9
0
    def tables(self, schema=None) -> List:
        """
        List all available tables on the indicated schema. If no schema is specified, assume public schema
        :param schema: optional schema name
        :return: list of tablenames
        """
        if schema is None:
            schema = self.SCHEMA_DEFAULT

        result = []
        qry = Select(PgSqlDialect()).from_('pg_tables', ['tablename']).where(
            'schemaname', '=', schema)
        with self._db.cursor() as c:
            for r in c.fetchall(*qry.assemble()):
                result.append(r['tablename'])
            return result
예제 #10
0
    def user_groups(self, user_name: str) -> List[str]:
        """
        List all groups associated with a given user
        :param user_name: user name to check
        :return: list of group names
        """
        qry = Select(PgSqlDialect()) \
            .from_('pg_user', {'rolname': 'name'}) \
            .join('pg_auth_members', 'member', 'pg_user', 'usesysid') \
            .join('pg_roles', 'oid', 'pg_auth_members', 'roleid') \
            .where('usename', '=', user_name)

        result = []
        with self._db.cursor() as c:
            for r in c.fetchall(*qry.assemble()):
                result.append(r['name'])
        return result