【问题标题】:Append pyodbc.Rows into a data frame using a loop使用循环将 pyodbc.Rows 附加到数据框中
【发布时间】:2018-06-17 16:25:30
【问题描述】:

我正在尝试将一些数据从 sql 服务器导入到 python。我想逐行导入数据并将其迭代地附加到数据框中。

到目前为止我的代码是:

data_NS = pd.DataFrame(columns=Fields_NS)
i=0

while(i < 10):
    row = cursor.fetchone()
    rowAsList = list(row)
    data_NS.append(rowAsList)
    i = i+1
conn.close()

data_NS 的结果是空数据框。 我没有收到任何错误消息,因此我们将不胜感激。

【问题讨论】:

  • 您能发布最小、完整和可验证的示例吗? stackoverflow.com/help/mcve
  • 我认为您可能想使用 fetchall() 并遍历该响应。
  • rowAsList = [x for x in row] 有点多余。也许list(row)?此外,您应该使用for 循环进行一定次数的迭代,而不是使用带有外部计数器的while 循环。
  • sql文件太大,无法使用fetchall(),返回内存问题错误。至于 while 循环,一旦解决了上述问题,我打算让它遍历整个文件。

标签: python sql pandas pyodbc


【解决方案1】:

您的 DataFrame 仍为空,因为 DataFrame.append

将其他行追加到此帧的末尾,返回一个新对象

(强调我的。)所以简单地做

data_NS.append(...)

将采用现有的data_NS 帧,将内容附加到其中,并将结果作为新帧返回,然后将其丢弃,因为它没有分配给变量。

我认为你实际上是在尝试做更多这样的事情:

fields_NS = ["id", "txt"]
data_NS = pd.DataFrame(columns=fields_NS)

sql = """\
SELECT 1 AS id, 'foo' as txt
UNION ALL
SELECT 2 AS id, 'bar' as txt
"""
crsr.execute(sql)

i = 0
while i < 10:
    row = crsr.fetchone()
    if not row:
        break
    row_as_dict = dict(zip(fields_NS, row))
    data_NS = data_NS.append(row_as_dict, ignore_index=True)
    i += 1

但请注意,这种逐行追加可能会相当慢。

【讨论】:

  • 这很完美!您能解释一下为什么需要将行对象转换为字典吗?
  • append 似乎不喜欢简单的有序值列表。它似乎想要一个名称/值对的字典,以便它可以将正确的值插入框架中的适当列。
【解决方案2】:

我会这样尝试:

connection = pyodbc.connect('your server information')
query = 'SELECT TOP 100 * FROM table'
df = pd.read_sql_query(query, connection)

为避免内存错误,只需调整您的查询并仅选择您需要的列,或者根据您查询的数据库类型使用“TOP”或类似的东西调整您带回的行数。

【讨论】:

  • 这种方法似乎比单独追加每一行快100倍左右
猜你喜欢
  • 2021-09-22
  • 2018-07-20
  • 2019-01-30
  • 2021-03-15
  • 2019-07-12
  • 2019-11-01
  • 2017-10-12
  • 2017-03-22
  • 2019-04-13
相关资源
最近更新 更多