Beispiel #1
0
 def get_table_description(self, cursor, table_name):
     "Returns a description of the table, with the DB-API cursor.description interface."
     return [
         FieldInfo(
             info['name'],
             info['type'],
             None,
             info['size'],
             None,
             None,
             info['null_ok'],
             info['default'],
         ) for info in self._table_info(cursor, table_name)
     ]
Beispiel #2
0
 def get_table_description(self, cursor, table_name):
     "Returns a description of the table, with the DB-API cursor.description interface."
     self.cache_bust_counter += 1
     cursor.execute("SELECT * FROM {} WHERE ROWNUM < 2 AND {} > 0".format(
         self.connection.ops.quote_name(table_name),
         self.cache_bust_counter))
     description = []
     for desc in cursor.description:
         name = force_text(
             desc[0]
         )  # cx_Oracle always returns a 'str' on both Python 2 and 3
         name = name % {
         }  # cx_Oracle, for some reason, doubles percent signs.
         description.append(FieldInfo(*(name.lower(), ) + desc[1:]))
     return description
Beispiel #3
0
def get_table_description(connection, cursor, table_name):
    "Returns a description of the table, with the DB-API cursor.description interface."
    # As cursor.description does not return reliably the nullable property,
    # we have to query the information_schema (#7783)
    # cursor.execute("""
    #     SELECT column_name, is_nullable, column_default
    #     FROM information_schema.columns
    #     WHERE table_name = %s""", [table_name])
    # field_map = {line[0]: line[1:] for line in cursor.fetchall()}
    cursor.execute("SELECT * FROM %s LIMIT 1" %
                   connection.ops.quote_name(table_name))
    return [
        FieldInfo(*((force_text(line[0]), ) + line[1:6] + (False, None)))
        for line in cursor.description
    ]
Beispiel #4
0
 def get_table_description(self, cursor, table_name):
     cursor.execute(
         """
         SELECT column_name, is_nullable, NULL AS column_default
         FROM information_schema.columns
         WHERE table_name = ?
           AND table_schema = CURRENT_SCHEMA()""", [table_name])
     field_map = {line[0]: line[1:] for line in cursor.fetchall()}
     cursor.execute('SELECT * FROM {} LIMIT 1'.format(
         self.connection.ops.quote_name(table_name)))
     return [
         FieldInfo(*((force_text(line[0]), ) + line[1:6] +
                     (field_map[force_text(line[0])][0] == 'YES',
                      field_map[force_text(line[0])][1])))
         for line in cursor.description
     ]
Beispiel #5
0
    def get_table_description(self, cursor, table_name):
        """
        Returns a description of the table, with the DB-API cursor.description interface."
        """
        # information_schema database gives more accurate results for some figures:
        # - varchar length returned by cursor.description is an internal length,
        #   not visible length (#5725)
        # - precision and scale (for decimal fields) (#5014)
        # - auto_increment is not available in cursor.description

        # 如何获取cursor呢?
        # 1. 获取所有的column的信息
        cursor.execute("""
            SELECT column_name, data_type, character_maximum_length, numeric_precision,
                   numeric_scale, extra, column_default
            FROM information_schema.columns
            WHERE table_name = %s AND table_schema = DATABASE()""", [table_name])

        # 数据Demo:
        # col_name data_type max_len num_prec num_scale extra column_default
        # (u'id',      u'int', None, 10L, 0L, u'auto_increment', None),
        # (u'user_id', u'int', None, 10L, 0L, u'', None),
        field_info = {line[0]: InfoLine(*line) for line in cursor.fetchall()}


        # 2. 获取一行数据?
        cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name))
        to_int = lambda i: int(i) if i is not None else i
        fields = []
        for line in cursor.description:
            # ('id',      3, 1, 11, 11, 0, 0),
            # ('user_id', 3, 2, 11, 11, 0, 0)
            col_name = force_text(line[0])

            # tuple相加,然后再展开
            # name type_code display_size internal_size precision scale null_ok
            fields.append(
                FieldInfo(*((col_name,)
                            + line[1:3]
                            + (to_int(field_info[col_name].max_len) or line[3],
                               to_int(field_info[col_name].num_prec) or line[4],
                               to_int(field_info[col_name].num_scale) or line[5])
                            + (line[6],)
                            + (field_info[col_name].extra,)
                            + (field_info[col_name].column_default,)))
            )
        return fields
Beispiel #6
0
    def get_table_description(self, cursor, table_name):
        """
        Return a description of the table with the DB-API cursor.description
        interface."
        """
        # information_schema database gives more accurate results for some figures:
        # - varchar length returned by cursor.description is an internal length,
        #   not visible length (#5725)
        # - precision and scale (for decimal fields) (#5014)
        # - auto_increment is not available in cursor.description
        cursor.execute("""
            SELECT
                column_name, data_type, character_maximum_length,
                numeric_precision, numeric_scale, extra, column_default,
                CASE
                    WHEN column_type LIKE '%% unsigned' THEN 1
                    ELSE 0
                END AS is_unsigned
            FROM information_schema.columns
            WHERE table_name = %s AND table_schema = DATABASE()""", [table_name])
        field_info = {line[0]: InfoLine(*line) for line in cursor.fetchall()}

        cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name))

        def to_int(i):
            return int(i) if i is not None else i

        fields = []
        for line in cursor.description:
            col_name = line[0]
            fields.append(
                FieldInfo(*(
                    (col_name,) +
                    line[1:3] +
                    (
                        to_int(field_info[col_name].max_len) or line[3],
                        to_int(field_info[col_name].num_prec) or line[4],
                        to_int(field_info[col_name].num_scale) or line[5],
                        line[6],
                        field_info[col_name].column_default,
                        field_info[col_name].extra,
                        field_info[col_name].is_unsigned,
                    )
                ))
            )
        return fields
Beispiel #7
0
 def get_table_description(self, cursor, table_name):
     """
     Return a description of the table with the DB-API cursor.description
     interface.
     """
     # As cursor.description does not return reliably the nullable property,
     # we have to query the information_schema (#7783)
     cursor.execute("""
         SELECT column_name, is_nullable, column_default
         FROM information_schema.columns
         WHERE table_name = %s""", [table_name])
     field_map = {line[0]: line[1:] for line in cursor.fetchall()}
     cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name))
     return [
         FieldInfo(*line[0:6], field_map[line.name][0] == 'YES', field_map[line.name][1])
         for line in cursor.description
     ]
Beispiel #8
0
        def get_table_description(self, cursor, table_name):
            """
            Returns a description of the table, with the DB-API
            cursor.description interface."
            """
            # - information_schema database gives more accurate results for
            #   some figures:
            # - varchar length returned by cursor.description is an internal
            #   length, not visible length (#5725)
            # - precision and scale (for decimal fields) (#5014)
            # - auto_increment is not available in cursor.description

            InfoLine = namedtuple('InfoLine', 'col_name data_type max_len '
                                  'num_prec num_scale extra column_default')
            cursor.execute("""
                SELECT column_name, data_type, character_maximum_length,
                numeric_precision, numeric_scale, extra, column_default
                FROM information_schema.columns
                WHERE table_name = %s AND table_schema = DATABASE()""",
                           [table_name])
            field_info = dict(
                (line[0], InfoLine(*line)) for line in cursor.fetchall()
            )

            cursor.execute("SELECT * FROM %s LIMIT 1"
                           % self.connection.ops.quote_name(table_name))
            to_int = lambda i: int(i) if i is not None else i
            fields = []
            for line in cursor.description:
                col_name = force_text(line[0])
                fields.append(
                    FieldInfo(*(
                        (col_name,) +
                        line[1:3] +
                        (
                            to_int(field_info[col_name].max_len) or line[3],
                            to_int(field_info[col_name].num_prec) or line[4],
                            to_int(field_info[col_name].num_scale) or line[5],
                            line[6],
                            field_info[col_name].column_default,
                            field_info[col_name].extra,
                        )
                    ))
                )
            return fields
 def get_table_description(self, cursor, table_name):
     """
     Return a description of the table with the DB-API cursor.description
     interface.
     """
     return [
         FieldInfo(
             info["name"],
             info["type"],
             None,
             info["size"],
             None,
             None,
             info["null_ok"],
             info["default"],
         )
         for info in self._table_info(cursor, table_name)
     ]
Beispiel #10
0
    def get_table_description(self, cursor, table_name):
        """
        Returns a description of the table, with the DB-API cursor.description interface.
        Must return a 'FieldInfo' struct 'name type_code display_size internal_size precision scale null_ok'
        """
        cursor.execute("""
            select
              trim(rf.rdb$field_name)
              , case
                  when (f.rdb$field_type in (7,8,16)) and (f.rdb$field_sub_type > 0) then
                    160 + f.rdb$field_sub_type
                  when (f.rdb$field_type = 261) then
                    260 + f.rdb$field_sub_type
                  else
                    f.rdb$field_type
                end as type_code

              , case
                  when (f.rdb$field_type in (14,37)) then
                    f.rdb$character_length
                  else
                    f.rdb$field_length
                end as field_length
              , f.rdb$field_precision
              , f.rdb$field_scale * -1
              , rf.rdb$null_flag
              , rf.rdb$default_source
              , c.rdb$collation_name
            from
              rdb$relation_fields rf
                join rdb$fields f on (rf.rdb$field_source = f.rdb$field_name)
                join rdb$collations c on (rf.rdb$collation_id = c.rdb$collation_id)
            where
              rf.rdb$relation_name = '%s'
            order by
              rf.rdb$field_position
            """ % (table_name.strip().upper(), ))
        items = []
        for r in cursor.fetchall():
            # name type_code display_size internal_size precision scale null_ok, default, collation
            items.append(
                FieldInfo(self.identifier_converter(r[0]), r[1], r[2], r[2]
                          or 0, r[3], r[4], not (r[5] == 1), r[6], r[7]))
        return items
Beispiel #11
0
 def get_table_description(self, cursor, table_name):
     """
     Return a description of the table with the DB-API cursor.description
     interface.
     """
     # Query the pg_catalog tables as cursor.description does not reliably
     # return the nullable property and information_schema.columns does not
     # contain details of materialized views.
     cursor.execute(
         """
         SELECT
             a.attname AS column_name,
             NOT (a.attnotnull OR (t.typtype = 'd' AND t.typnotnull)) AS is_nullable,
             pg_get_expr(ad.adbin, ad.adrelid) AS column_default,
             CASE WHEN collname = 'default' THEN NULL ELSE collname END AS collation
         FROM pg_attribute a
         LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum
         LEFT JOIN pg_collation co ON a.attcollation = co.oid
         JOIN pg_type t ON a.atttypid = t.oid
         JOIN pg_class c ON a.attrelid = c.oid
         JOIN pg_namespace n ON c.relnamespace = n.oid
         WHERE c.relkind IN ('f', 'm', 'p', 'r', 'v')
             AND c.relname = %s
             AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
             AND pg_catalog.pg_table_is_visible(c.oid)
     """,
         [table_name],
     )
     field_map = {line[0]: line[1:] for line in cursor.fetchall()}
     cursor.execute(
         "SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name)
     )
     return [
         FieldInfo(
             line.name,
             line.type_code,
             line.display_size,
             line.internal_size,
             line.precision,
             line.scale,
             *field_map[line.name],
         )
         for line in cursor.description
     ]
Beispiel #12
0
    def get_table_description(self, cursor, table_name):
        """Return a description of the table with the DB-API cursor.description
        interface.

        :type cursor: :class:`~google.cloud.spanner_dbapi.cursor.Cursor`
        :param cursor: A reference to a Spanner Database cursor.

        :type table_name: str
        :param table_name: The name of the table.

        :rtype: list
        :returns: A description of the table with the DB-API
                  cursor.description interface.
        """
        cursor.execute(
            "SELECT * FROM %s LIMIT 1"
            % self.connection.ops.quote_name(table_name)
        )
        column_details = cursor.get_table_column_schema(table_name)
        descriptions = []
        for line in cursor.description:
            column_name, type_code = line[0], line[1]
            details = column_details[column_name]
            if details.spanner_type.startswith("STRING"):
                # Extract the size of the string from, e.g. STRING(#).
                internal_size = details.spanner_type[7:-1]
                if internal_size != "MAX":
                    internal_size = int(internal_size)
            else:
                internal_size = None
            descriptions.append(
                FieldInfo(
                    column_name,
                    type_code,
                    None,  # display_size
                    internal_size,
                    None,  # precision
                    None,  # scale
                    details.null_ok,
                    None,  # default
                )
            )

        return descriptions
    def get_table_description(self, cursor, table_name):
        """
        Returns a description of the table, with the DB-API cursor.description interface.
        Must return a 'FieldInfo' struct 'name type_code display_size internal_size precision scale null_ok'
        """
        cursor.execute("""
            select
              trim(rf.rdb$field_name)
              , case
                  when (f.rdb$field_type in (7,8,16)) and (f.rdb$field_sub_type > 0) then
                    160 + f.rdb$field_sub_type
                  when (f.rdb$field_type = 261) then
                    260 + f.rdb$field_sub_type
                  else
                    f.rdb$field_type
                end as type_code

              , case
                  when (f.rdb$field_type in (14,37)) then
                    f.rdb$character_length
                  else
                    f.rdb$field_length
                end as field_length
              , f.rdb$field_precision
              , f.rdb$field_scale * -1
              , rf.rdb$null_flag
              , rf.rdb$default_source
              /*RDB$IDENTITY_TYPE stores the value 0 for GENERATED ALWAYS, 
              1 for GENERATED BY DEFAULT, and NULL for non-identity columns.*/
              ,NULL as rdb$identity_type  /*ToDo: In Firebird 3.0 or hight, this fields exists as: rf.rdb$identity_type*/
            from
              rdb$relation_fields rf join rdb$fields f on (rf.rdb$field_source = f.rdb$field_name)
            where
              rf.rdb$relation_name = '%s'
            order by
              rf.rdb$field_position
            """ % (table_name.strip().upper(), ))
        items = []
        for r in cursor.fetchall():
            # name type_code display_size internal_size precision scale null_ok, default, identity_type
            items.append(
                FieldInfo(self.identifier_converter(r[0]), r[1], r[2], r[2]
                          or 0, r[3], r[4], not (r[5] == 1), r[6], r[7]))
        return items
Beispiel #14
0
    def get_table_description(self, cursor, table_name):
        "Returns a description of the table, with the DB-API cursor.description interface."
        query_format = """SELECT c.* FROM syscolumns c JOIN systables t
                        ON c.tabid=t.tabid WHERE t.tabname='{}'"""

        cursor.execute(query_format.format(table_name))
        columns = [[c[0], c[3] % 256, None, c[4], c[4], None, 0 if c[3] > 256 else 1, None]
                   for c in cursor.fetchall()]
        items = []
        for column in columns:
            if column[1] in [SQL_TYPE_NUMERIC, SQL_TYPE_DECIMAL]:
                column[4] = int(column[3] / 256)
                column[5] = column[3] - column[4] * 256
            # FieldInfo = namedtuple('FieldInfo', 'name type_code display_size internal_size precision scale null_ok default')
            # The named tuple above will help decypher the introspection process.
            # We care alot about the type column
            items.append(FieldInfo(*column))

        return items
Beispiel #15
0
    def get_table_description(self, cursor, table_name, identity_check=True):
        """Returns a description of the table, with DB-API cursor.description interface.

        The 'auto_check' parameter has been added to the function argspec.
        If set to True, the function will check each of the table's fields for the
        IDENTITY property (the IDENTITY property is the MSSQL equivalent to an AutoField).

        When an integer field is found with an IDENTITY property, it is given a custom field number
        of SQL_AUTOFIELD, which maps to the 'AutoField' value in the DATA_TYPES_REVERSE dict.

        When a bigint field is found with an IDENTITY property, it is given a custom field number
        of SQL_BIGAUTOFIELD, which maps to the 'BigAutoField' value in the DATA_TYPES_REVERSE dict.
        """

        # map pyodbc's cursor.columns to db-api cursor description
        columns = [[c[3], c[4], None, c[6], c[6], c[8], c[10], c[12]]
                   for c in cursor.columns(table=table_name)]

        items = []
        for column in columns:
            if VERSION >= (3, 2):
                if self.connection.sql_server_version >= 2019:
                    sql = """SELECT collation_name
                            FROM sys.columns c
                            inner join sys.tables t on c.object_id = t.object_id
                            WHERE t.name = '%s' and c.name = '%s'
                            """ % (table_name, column[0])
                    cursor.execute(sql)
                    collation_name = cursor.fetchone()
                    column.append(collation_name[0] if collation_name else '')
                else:
                    column.append('')

            if identity_check and self._is_auto_field(cursor, table_name,
                                                      column[0]):
                if column[1] == Database.SQL_BIGINT:
                    column[1] = SQL_BIGAUTOFIELD
                else:
                    column[1] = SQL_AUTOFIELD
            if column[1] == Database.SQL_WVARCHAR and column[3] < 4000:
                column[1] = Database.SQL_WCHAR
            items.append(FieldInfo(*column))
        return items
Beispiel #16
0
 def get_table_description(self, cursor, table_name):
     colspecs = collections.defaultdict(lambda: dict(
         types=collections.Counter(),
         specs=collections.defaultdict(int),
     ))
     fields = cursor.db_conn['__schema__'].find_one(
         {'name': table_name}, {'fields': True})['fields']
     columns = []
     for name, properties in fields.items():
         columns.append(
             FieldInfo(name=name,
                       type_code=properties['type_code'],
                       display_size=None,
                       internal_size=None,
                       precision=None,
                       scale=None,
                       null_ok=None,
                       default=None))
     return columns
Beispiel #17
0
 def get_table_description(self, cursor, table_name):
     "Returns a description of the table, with the DB-API cursor.description interface."
     # As cursor.description does not return reliably the nullable property,
     # we have to query the information_schema (#7783)
     # HACK: limit on supported schemas, adding table_schema constraint
     cursor.execute("""
         SELECT column_name, is_nullable, column_default
         FROM information_schema.columns
         WHERE table_name = %s
           AND table_schema IN %s""", [table_name, self._supported_schemas])
     field_map = {line[0]: line[1:] for line in cursor.fetchall()}
     cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name))
     return [
         FieldInfo(*(
             (force_text(line[0]),) +
             line[1:6] +
             (field_map[force_text(line[0])][0] == 'YES', field_map[force_text(line[0])][1])
         )) for line in cursor.description
     ]
 def get_table_description(self, cursor, table_name):
     "Returns a description of the table, with the DB-API cursor.description interface."
     # As cursor.description does not return reliably the nullable property,
     # we have to query the information_schema (#7783)
     cursor.execute(
         """
         SELECT column_name, is_nullable, column_default
         FROM information_schema.columns
         WHERE table_schema = %s and table_name = %s""",
         [self.connection._schema.schema_name, table_name],
     )
     field_map = {line[0]: line[1:] for line in cursor.fetchall()}
     cursor.execute("SELECT * FROM %s LIMIT 1" %
                    self.connection.ops.quote_name(table_name))
     return [
         FieldInfo(*((force_str(line[0]), ) + line[1:6] +
                     (field_map[force_str(line[0])][0] == "YES",
                      field_map[force_str(line[0])][1])))
         for line in cursor.description
     ]
Beispiel #19
0
    def get_table_description(self, cursor, table_name, identity_check=True):
        """Returns a description of the table, with DB-API cursor.description interface.

        The 'auto_check' parameter has been added to the function argspec.
        If set to True, the function will check each of the table's fields for the
        IDENTITY property (the IDENTITY property is the MSSQL equivalent to an AutoField).

        When a field is found with an IDENTITY property, it is given a custom field number
        of SQL_AUTOFIELD, which maps to the 'AutoField' value in the DATA_TYPES_REVERSE dict.
        """

        # map pyodbc's cursor.columns to db-api cursor description
        columns = [[c[3], c[4], None, c[6], c[6], c[8], c[10], c[12]] for c in cursor.columns(table=table_name)]
        items = []
        for column in columns:
            if identity_check and self._is_auto_field(cursor, table_name, column[0]):
                column[1] = SQL_AUTOFIELD
            if column[1] == Database.SQL_WVARCHAR and column[3] < 4000:
                column[1] = Database.SQL_WCHAR
            items.append(FieldInfo(*column))
        return items
    def get_table_description(self, cursor, table_name):
        """
        Returns a description of the table, with the DB-API cursor.description interface.
        """

        # As cursor.description does not return reliably the nullable property,
        # we have to query the information_schema (#7783)
        cursor.execute(self._get_table_description_query, {
            'schema': self.connection.schema_name,
            'table': table_name
        })
        field_map = {line[0]: line[1:] for line in cursor.fetchall()}
        cursor.execute('SELECT * FROM %s LIMIT 1' %
                       self.connection.ops.quote_name(table_name))

        return [
            FieldInfo(*((force_text(line[0]), ) + line[1:6] +
                        (field_map[force_text(line[0])][0] == 'YES',
                         field_map[force_text(line[0])][1])))
            for line in cursor.description
        ]
        def get_table_description(self, cursor, table_name):
            """
            Returns a description of the table, with the DB-API
            cursor.description interface.
            """
            # varchar length returned by cursor.description is an internal
            # length not visible length (#5725), use information_schema database
            #  to fix this
            cursor.execute(
                "SELECT column_name, character_maximum_length "
                "FROM INFORMATION_SCHEMA.COLUMNS "
                "WHERE table_name = %s AND table_schema = DATABASE() "
                "AND character_maximum_length IS NOT NULL", [table_name])
            length_map = dict(cursor.fetchall())

            # Also getting precision and scale from
            # information_schema (see #5014)
            cursor.execute(
                "SELECT column_name, numeric_precision, numeric_scale FROM "
                "INFORMATION_SCHEMA.COLUMNS WHERE table_name = %s AND "
                "table_schema = DATABASE() AND data_type='decimal'",
                [table_name])
            numeric_map = dict((line[0], tuple([int(n) for n in line[1:]]))
                               for line in cursor.fetchall())

            cursor.execute("SELECT * FROM {0} LIMIT 1".format(
                self.connection.ops.quote_name(table_name)))

            if django.VERSION >= (1, 6):
                return [
                    FieldInfo(*((force_text(line[0]), ) + line[1:3] +
                                (length_map.get(line[0], line[3]), ) +
                                numeric_map.get(line[0], line[4:6]) +
                                (line[6], ))) for line in cursor.description
                ]
            else:
                return [
                    line[:3] + (length_map.get(line[0], line[3]), ) + line[4:]
                    for line in cursor.description
                ]
Beispiel #22
0
    def get_table_description(self, cursor, table_name, identity_check=True):
        """Return a description of the table, with DB-API cursor.description interface.

        The 'auto_check' parameter has been added to the function argspec.
        If set to True, the function will check each of the table's fields for the
        IDENTITY property (the IDENTITY property is the MSSQL equivalent to an AutoField).

        When a field is found with an IDENTITY property, it is given a custom field number
        of SQL_AUTOFIELD, which maps to the 'AutoField' value in the DATA_TYPES_REVERSE dict.
        """
        table_field_type_map = self._get_table_field_type_map(
            cursor, table_name)

        cursor.execute("SELECT * FROM [%s] where 1=0" % (table_name))
        columns = cursor.description

        items = list()
        for column in columns:
            column = list(column)  # Convert tuple to list
            # fix data type
            data_type, char_length = table_field_type_map.get(column[0])
            column[1] = self._datatype_to_ado_type(data_type)

            if identity_check and self._is_auto_field(cursor, table_name,
                                                      column[0]):
                if column[1] == ado_consts.adBigInt:
                    column[1] = BIG_AUTO_FIELD_MARKER
                else:
                    column[1] = AUTO_FIELD_MARKER

            if column[1] == MONEY_FIELD_MARKER:
                # force decimal_places=4 to match data type. Cursor description thinks this column is a string
                column[5] = 4
            elif column[1] == ado_consts.adVarWChar and char_length == -1:
                # treat varchar(max) as text
                column[1] = self._datatype_to_ado_type('text')
            items.append(FieldInfo(*column))
        return items
 def get_table_description(self, cursor, table_name):
     """
     Return a description of the table with the DB-API cursor.description
     interface.
     """
     # user_tab_columns gives data default for columns
     cursor.execute("""
         SELECT
             column_name,
             data_default,
             CASE
                 WHEN char_used IS NULL THEN data_length
                 ELSE char_length
             END as internal_size
         FROM user_tab_cols
         WHERE table_name = UPPER(%s)""", [table_name])
     field_map = {
         column: (internal_size, default if default != 'NULL' else None)
         for column, default, internal_size in cursor.fetchall()
     }
     self.cache_bust_counter += 1
     cursor.execute("SELECT * FROM {} WHERE ROWNUM < 2 AND {} > 0".format(
         self.connection.ops.quote_name(table_name),
         self.cache_bust_counter))
     description = []
     for desc in cursor.description:
         name = force_text(desc[0])  # cx_Oracle always returns a 'str'
         internal_size, default = field_map[name]
         name = name % {}  # cx_Oracle, for some reason, doubles percent signs.
         description.append(FieldInfo(*(
             (name.lower(),) +
             desc[1:3] +
             (internal_size, desc[4] or 0, desc[5] or 0) +
             desc[6:] +
             (default,)
         )))
     return description
Beispiel #24
0
 def get_table_description(self, cursor, table_name):
     """
     Returns a description of the table, with the DB-API cursor.description interface.
     Must return a 'FieldInfo' struct 'name type_code display_size internal_size precision scale null_ok'
     """
     tbl_name = "'%s'" % table_name.upper()
     cursor.execute("""
         select
           lower(trim(rf.rdb$field_name))
           , case
               when (f.rdb$field_type in (7,8,16)) and (f.rdb$field_sub_type > 0) then
                 160 + f.rdb$field_sub_type
               when (f.rdb$field_type = 261) then
                 260 + f.rdb$field_sub_type
               else
                 f.rdb$field_type
             end as type_code
           , f.rdb$field_length
           , f.rdb$field_precision
           , f.rdb$field_scale * -1
           , rf.rdb$null_flag
           , rf.rdb$default_source
         from
           rdb$relation_fields rf join rdb$fields f on (rf.rdb$field_source = f.rdb$field_name)
         where
           upper(rf.rdb$relation_name) = %s
         order by
           rf.rdb$field_position
         """ % (tbl_name, ))
     items = []
     for r in cursor.fetchall():
         # name type_code display_size internal_size precision scale null_ok
         items.append(
             FieldInfo(r[0], r[1], r[2], r[2] or 0, r[3], r[4],
                       not (r[5] == 1), r[6]))
     return items
Beispiel #25
0
    def test_get_table_description(self):
        """
        Tests get table description method.
        """
        db_introspection = DatabaseIntrospection(self.connection)
        cursor = mock.MagicMock()

        def description(*args, **kwargs):
            return [["name", TypeCode.STRING], ["age", TypeCode.INT64]]

        def get_table_column_schema(*args, **kwargs):
            column_details = {}
            column_details["name"] = ColumnDetails(null_ok=False,
                                                   spanner_type="STRING(10)")
            column_details["age"] = ColumnDetails(null_ok=True,
                                                  spanner_type="INT64")
            return column_details

        cursor.get_table_column_schema = get_table_column_schema
        cursor.description = description()
        table_description = db_introspection.get_table_description(
            cursor=cursor, table_name="Table_1")
        if USING_DJANGO_3:
            self.assertEqual(
                table_description,
                [
                    FieldInfo(
                        name="name",
                        type_code=TypeCode.STRING,
                        display_size=None,
                        internal_size=10,
                        precision=None,
                        scale=None,
                        null_ok=False,
                        default=None,
                        collation=None,
                    ),
                    FieldInfo(
                        name="age",
                        type_code=TypeCode.INT64,
                        display_size=None,
                        internal_size=None,
                        precision=None,
                        scale=None,
                        null_ok=True,
                        default=None,
                        collation=None,
                    ),
                ],
            )
        else:
            self.assertEqual(
                table_description,
                [
                    FieldInfo(
                        name="name",
                        type_code=TypeCode.STRING,
                        display_size=None,
                        internal_size=10,
                        precision=None,
                        scale=None,
                        null_ok=False,
                        default=None,
                    ),
                    FieldInfo(
                        name="age",
                        type_code=TypeCode.INT64,
                        display_size=None,
                        internal_size=None,
                        precision=None,
                        scale=None,
                        null_ok=True,
                        default=None,
                    ),
                ],
            )
    def get_table_description(self, cursor, table_name):
        colspecs = collections.defaultdict(lambda: dict(
            types=collections.Counter(),
            specs=collections.defaultdict(int),
        ))
        fields = cursor.db_conn['__schema__'].find_one(
            {'name': table_name}, {'fields': True})['fields']
        columns = []
        for name, properties in fields.items():
            columns.append(
                FieldInfo(name=name,
                          type_code=properties['type_code'],
                          display_size=None,
                          internal_size=None,
                          precision=None,
                          scale=None,
                          null_ok=None,
                          default=None))
        return columns
        results = cursor.db_conn[table_name].aggregate([
            {
                '$sample': {
                    'size': self.SAMPLE_SIZE
                }
            },
        ])
        for result in results:
            for k, v in result.items():
                column = colspecs[k]
                specs = column['specs']

                column['types'][type(v)] += 1

                if isinstance(v, str):
                    specs['length'] = max(specs['length'], len(str(v)))

                if isinstance(v, (int, bson.int64.Int64, float)):
                    specs['max_value'] = max(specs['max_value'], v)

                if isinstance(v, float):
                    # Convert to string and count the characters after the .
                    precision = len(str(v).split('.')[1])
                    specs['precision'] = max(specs['precision'], precision)

        columns = []
        for name, column in colspecs.items():
            types = column['types']
            specs = column['specs']

            if type(None) in types:
                nullable = True
                del types[type(None)]
            else:
                nullable = False

            for from_, count in list(types.items()):
                to = self.TYPE_MAPPING.get(from_)
                if to:
                    types[to] = types.pop(from_)

            type_ = types.most_common(1)[0][0]
            if type_ == str and specs['length'] > 200:
                type_ = 'text'
                del specs['length']

            if len(types) > 1:
                print('# Found multiple types for %s.%s: %s' %
                      (table_name, name, types))

            columns.append(
                FieldInfo(
                    name,  # name
                    type_,  # type_code
                    specs.get('length'),  # display size
                    specs.get('length'),  # internal size
                    specs.get('precision'),  # precision
                    None,  # scale
                    nullable,  # nullable
                    None,  # default
                ))

        return columns
    def get_table_description(self, cursor, table_name):
<<<<<<< HEAD
        "Returns a description of the table, with the DB-API cursor.description interface."
=======
        """
        Return a description of the table with the DB-API cursor.description
        interface.
        """
>>>>>>> 37c99181c9a6b95433d60f8c8ef9af5731096435
        return [
            FieldInfo(
                info['name'],
                info['type'],
                None,
                info['size'],
                None,
                None,
                info['null_ok'],
                info['default'],
            ) for info in self._table_info(cursor, table_name)
        ]

<<<<<<< HEAD
=======
    def get_sequences(self, cursor, table_name, table_fields=()):
        pk_col = self.get_primary_key_column(cursor, table_name)
        return [{'table': table_name, 'column': pk_col}]

>>>>>>> 37c99181c9a6b95433d60f8c8ef9af5731096435
    def column_name_converter(self, name):
        """