Firebird 检查列中的类型

Firebird checking types within columns

我想 运行 一些类似于 cur.execute('stuff') 行中伪代码的内容:

import fdb

tableName = "MostCertainlyNotHelloWorldTable"

con = fdb.connect(dsn="dsnString",user="MostCertainlyNotSYSDBA",password="MostCertainlyNotMasterkey")
cur = con.cursor()

# this is my pseudo-code
cur.execute("SELECT * FROM tableName WHERE Type(column) IS NOT BLOB") 
# The idea is to remove all BLOB type columns within a given table from the SELECT command's output for that table

for row in cur.fetchall():
    for col in row:
        print(col, end = ',')
    print()

我需要从 firebird 数据库打印给定 table 内的所有列,除了(如代码注释中所述)那些以 "BLOB" 作为输入类型的列。公平地说,我不打算打印东西,实际上我打算将它们附加到一个文本文件中,但我想打印会产生相同的结果(我认为?)而不会淹没项目文件夹。

我想要一些允许我按类型过滤数据的东西 - 即排除 BLOB - 但仍然允许我获得类似 csv 的格式(行中的列由单个逗号分隔,行由 '\ n').

如果无法过滤掉 BLOB,我需要一种方法来处理值中包含逗号的 BLOB 列,因为它们有效地破坏了我的 table 的结构。

所以我需要:

正如我之前评论的那样,您不能在查询本身中执行此操作。您必须检查元数据表并构建仅包含相关列的适当查询,或者您需要对游标进行类型自省并使用 blob 跳过列。

例如,要跳过 FDB 中的 blob 列,您可以这样做:

import fdb
import csv

def is_blob(descriptor):
    return (descriptor[fdb.DESCRIPTION_DISPLAY_SIZE] == 0 
        and descriptor[fdb.DESCRIPTION_INTERNAL_SIZE] == 8)

with fdb.connect(dsn="localhost:exampledb", user="sysdba", password="masterkey") as con:
    cur = con.cursor()
    cur.execute("SELECT * FROM DATAEXAMPLE") 

    with open('output.csv', 'w', newline='') as csvfile:
        writer = csv.writer(csvfile)
        for row in cur.fetchall():
            values = [column for index, column in enumerate(row) 
                        if not is_blob(cur.description[index])]
            writer.writerow(values)

检查显示大小 0 和内部大小 8 将识别斑点。这有点混乱,但是 Cursor.description 中的 type_code (fdb.DESCRIPTION_TYPE_CODE) 没有提供足够的信息来区分 blob 和非 blob。

我也在使用 csv module 生成 CSV 文件。这将通过引用值解决例如 varchar 列在其值中包含逗号的问题。如果您需要微调生成的 CSV 文件,请查看 csv 的文档。默认生成与 Microsoft Excel 读取和写入 CSV 的方式兼容的 CSV。

使用 CSV 模块还可以包含 blob 列(假设它们是 blob sub_type text)。这可能取决于消费者是否可以接受值内的换行符。如果您还有 blob sub_type binary 列,您可能需要为这些做一些额外的事情,例如在将值包含在 CSV 中之前对其进行 base64 编码。