【问题标题】:Why "name 'cursor' is not defined" when pyodbc cursor is in main()? [duplicate]当pyodbc游标位于main()中时,为什么“未定义名称'游标'”? [复制]
【发布时间】:2015-08-21 20:02:21
【问题描述】:

我正在从命令行运行一个压缩在下面的 Python 程序,它给了我一个错误 (name 'cursor' is not defined) 并指向底部附近的 cursor.fetchmany() 行。但是,如果我将main() 的前两行、conncursor 分配、main() 的上方和外部移动到程序的主体中,则程序将按需要运行。当我在main() 中分配cursor 时,为什么这不起作用?我很想知道这是否只是 pyodbc 库的一个怪癖,还是有更好的方法让它从 main() 内部工作,或者实际上可以将作业留在程序主体中。

import pyodbc
import csv
#   ...other modules...

def main():
    conn = pyodbc.connect(DSN=abcxyz, autocommit=True)
    cursor = conn.cursor()
#   ...sys.argv assignments and validation...
    pull_data(query_file, start_date, end_date, out_file)

def pull_data(query_file, start_date, end_date, out_file):
#   ...prepare query as string, date range as list...
    for date in list_dates:
        cursor.execute(query, date)
        append_rows(out_file)

def append_rows(out_file):
    with open(out_file, 'a', newline='') as file:
        writer = csv.writer(file)
        while True:
            results = cursor.fetchmany(chunk_size)
            if not results:
                break
            for result in results:
                writer.writerow(result)

if __name__ == '__main__':
    main()

【问题讨论】:

  • connmain 的本地,一个类会更好
  • 我想我同意——如果我想保证在发生错误时关闭数据库连接,我要么必须将 conncursor 都传递给几乎所有函数,或者我可以创建一个始终可以调用 db_close() 方法的对象。

标签: python pyodbc


【解决方案1】:

因为光标未在append_rows()pull_data() 中定义。您在main() 中定义它,所以它只能在main() 中访问。

解决此问题的最佳方法可能是将光标对象传递给append_rows()pull_data()

【讨论】:

  • 这是否意味着我需要将cursor 作为附加参数传递给pull_data() 并再次传递给append_rows()
  • @RobinFiveWords 是的。您可以在 main() 之外定义它,它会在全局范围内,但通常最好将其保留在本地范围内。
【解决方案2】:

您收到cursor 未定义错误的原因是因为它不存在于您的函数中。变量只存在于它们定义的范围内。

当您在 main 之外定义 cursor 时,它被声明为全局变量,这意味着它可以在脚本的所有范围内访问。

试试:

import pyodbc
import csv
#   ...other modules...

def main():
    # Since conn and cursor are being declared here, they only exist within the scope of this function, not other functions that are called.
    conn = pyodbc.connect(DSN=abcxyz, autocommit=True)
    cursor = conn.cursor()
#   ...sys.argv assignments and validation...
    # make sure we give the cursor to pull_data so it will exist in its scope!
    pull_data(query_file, start_date, end_date, out_file, cursor)

def pull_data(query_file, start_date, end_date, out_file, cursor):
#   ...prepare query as string, date range as list...
    for date in list_dates:
        cursor.execute(query, date)
        # Pass the cursor to append_rows
        append_rows(out_file, cursor)

# cursor is actually passed to the append_rows function. Now it exists in this scope
def append_rows(out_file, cursor):
    with open(out_file, 'a', newline='') as file:
        writer = csv.writer(file)
        while True:
            results = cursor.fetchall()
            for result in results:
                writer.writerow(result)

if __name__ == '__main__':
    main()

我还建议您阅读https://stackoverflow.com/a/292502/5249060

【讨论】:

    猜你喜欢
    • 2017-07-06
    • 2018-05-18
    • 1970-01-01
    • 2013-04-16
    • 1970-01-01
    • 2020-08-02
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多