关于python:当pyodbc游标在main()中时,为什么“name’gorm’没有定义”?

Why “name 'cursor' is not defined” when pyodbc cursor is in main()?

本问题已经有最佳答案,请猛点这里访问。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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()


您在未定义cursor时出错的原因是它不存在于您的函数中。变量只存在于其定义的范围内。

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

尝试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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。


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

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