【问题标题】:Pandas read_sql with pyodbc to handle corrupt data带有 pyodbc 的 Pandas read_sql 来处理损坏的数据
【发布时间】:2020-06-18 12:55:12
【问题描述】:

我正在与一个拥有 4D 数据库的客户合作。 Tableau 不会连接到它。 (这是另一个问题,如果你知道答案,请告诉我。)我们决定做的基本上是保留数据的两份副本。我正在用 Python 构建一个工具,它将从他们的数据库中获取任意表并将其副本存储在 MySQL 数据库中。然后它将定期运行并在添加新数据时更新数据。

我更喜欢使用 SqlAlchemy,但它不支持 4D。所以,我将 pyodbc 与熊猫一起使用。我正在使用

data_chunks = pandas.read_sql("SELECT * FROM table_name", con=pyodbc_connection, chunksize=100000)

然后我转身使用

chunk_df.to_sql("table_name", con=sqlalchemy_mysql_connection, index=False, if_exists="append")

将其写入 MySQL 数据库。

不幸的是,在我正在读取的一些表格中,存在损坏的数据,我收到 ValueErrorThe year xxxxx 超出范围。

跟踪中调用的最后一个函数是data = cursor.fetchmany(chunksize),我相信它来自pyodbc。

如何从任意表中读取数据,并能够优雅地处理损坏的数据并继续?

【问题讨论】:

  • 听起来您需要调整 MySQL 表的架构以允许此类“损坏”数据值。 Year 列可能具有允许值的约束。调整其他列。
  • @Parfait 在我尝试将其插入 MySQL 表之前它失败了。我很确定它在尝试将 SQL 数据类型转换为 Python 数据类型时失败了。
  • 所以你在执行read_sql时遇到了错误?
  • 请显示更完整的代码而不是行 sn-ps,包括完整的 SQL 语句,以便我们提供帮助。我们需要查看 year 对象。
  • 另外,xxxxx 年份值真的在range(1, 10000) 之外吗?如果是这样,那听起来像是 ODBC 驱动程序中的错误。

标签: python pandas sqlalchemy pyodbc 4d-database


【解决方案1】:

您可以想象使用 pyodbc Output Converter function 来拦截损坏的日期值并使用类似于以下的代码“修复”它们:

def unpack_sql_type_timestamp(raw_bytes):
    y, m, d, h, n, s, f = struct.unpack("<h5HI", raw_bytes)
    if y > 9999:
        y = 9999
    elif y < 1:
        y = 1
    return datetime.datetime(y, m, d, h, n, s, f)

pyodbc_connection = pyodbc.connect(connection_string)

pyodbc_connection.add_output_converter(
    pyodbc.SQL_TYPE_TIMESTAMP, 
    unpack_sql_type_timestamp
)

data_chunks = pandas.read_sql_query(
    "SELECT * FROM table_name", 
    con=pyodbc_connection, 
    chunksize=100000
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-16
    • 2017-02-14
    • 1970-01-01
    • 1970-01-01
    • 2018-07-12
    • 1970-01-01
    • 2015-11-13
    相关资源
    最近更新 更多