Python 通过尝试后抛出错误 - 除了块
Python Throwing Error After Passing Try - Except Block
我正在使用此脚本在 PostgreSQL“集群”中创建数据库和用户,然后创建存在于另一个模式中的新模式(我只复制它们的名称)。
我正在使用 Python 2.7.5,这是我的脚本:
import sys
import psycopg2
import getpass
def connect_db(database):
connection = psycopg2.connect(user="postgres",
password="mypass",
host="127.0.0.1",
port="5432",
database=str(database))
connection.autocommit = True
cursor = connection.cursor()
return cursor
def execute_query_2_select(cursor, query):
try:
cursor.execute(query)
output = cursor.fetchall()
return output
except Exception as e:
print(e)
def execute_query_2_create(cursor, query):
try:
cursor.execute(query)
except Exception as e:
print(e)
def main():
source_database = str(raw_input("Enter a tns name(DB_UNIQUE_NAME): ")).strip()
target_database = str(raw_input("Enter a username(OID): ")).strip()
user_password = str(getpass.getpass("Enter the password of" )).strip()
try:
cursor_source = connect_db(source_database)
except Exception:
print("Please check your input and try again.\n")
main()
query_2_get_schemas = "select schema_name from information_schema.schemata where schema_name not like 'pg_%' and schema_name not in ('public', 'information_schema');"
schema_template_list = execute_query_2_select(cursor_source, query_2_get_schemas)
cursor_source.close()
cursor_postgres = connect_db("postgres")
execute_query_2_create(cursor_postgres, "create user {x} with encrypted password '{y}';".format(x=target_database, y=user_password))
execute_query_2_create(cursor_postgres, "create database {x} owner {x};".format(x=target_database))
cursor_postgres.close()
cursor_target = connect_db(target_database)
for i in schema_template_list:
execute_query_2_create(cursor_target, "CREATE SCHEMA IF NOT EXISTS {x};".format(x=i[0]))
execute_query_2_create(cursor_target, "GRANT USAGE ON SCHEMA {x} TO {x};".format(x=i[0]))
execute_query_2_create(cursor_target, "GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA {x} TO {x};".format(x=i[0]))
execute_query_2_create(cursor_target, "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA {x} to {x};".format(x=i[0]))
execute_query_2_create(cursor_target, "ALTER DEFAULT PRIVILEGES IN SCHEMA {x} GRANT ALL PRIVILEGES ON TABLES TO {x};".format( x=i[0]))
execute_query_2_create(cursor_target, "ALTER DEFAULT PRIVILEGES IN SCHEMA {x} GRANT ALL PRIVILEGES ON SEQUENCES TO {x};".format( x=i[0]))
execute_query_2_create(cursor_target, "ALTER SCHEMA {x} OWNER TO {x};".format(x=i[0]))
print("Commands for schema {x} are executed!".format(x=i[0]))
cursor_target.close()
if __name__ == "__main__":
main()
因为异常块
except Exception:
print("Please check your input and try again.\n")
main()
如果用户提供了不正确的连接数据并再次输入,我将让用户返回并检查他们的输入。为了在第一次尝试时测试脚本,我提供了不正确的连接数据。然后它回到我想要它去的地方。最后,我提供了正确的信息,但这次我得到了“UnboundLocalError:局部变量 'cursor_source' 在赋值前被引用”。为什么?它在 second/later 次尝试中定义。
输出:
Enter a database name for schema pattern: asdaslkdjals
Enter a database/user name to create: asdasd
Enter the password of user asdasd
Please check your input and try again.
Enter a database name for schema pattern: test_source
Enter a database/user name to create: test_target
Enter the password of user test_target
Commands for schema test_schemaxx are executed!
Traceback (most recent call last):
File "schema.py", line 68, in <module>
main()
File "schema.py", line 44, in main
schema_template_list = execute_query_2_select(cursor_source, query_2_get_schemas)
UnboundLocalError: local variable 'cursor_source' referenced before assignment
你试过全局语句了吗?
例如,将全局放在一个循环中:
A = 20
def main():
print(‘Does Something’)
input = input(‘ variable a’s new value : ‘)
#input == 10
main()
如果您尝试访问函数内的变量,将会报错。但如果你这样做:
A = 20
def main():
global A
print(‘Does Something’)
input = input(‘ variable A’s new value : ‘)
#input == 10
main()
这将停止给出错误。
我不是 100% 了解您为什么要在本地解除绑定,但是从异常处理程序调用 main 绝对是个坏主意。
根据用户必须重试的次数,您可能会进入无限递归状态,并且可能会留下各种 half-initialized 连接。
相反,您应该在 while 循环中重试,这样您就不必退出主函数。
这是你给出的例子的递归程序流程:先是错误的输入,然后是正确的输入:
- 你打电话给
main
- 您在
try
中传递了错误的输入
- 执行
except
,再次调用main
- 你传递了很好的输入
try
执行没有问题
- 函数的其余部分 运行s 和 returns
- 递归调用结束 - 回到第一次调用.
- 现在第一个
main
保持 运行ning 没有 cursor_source
定义(因为try
失败)。
您基本上需要将所有代码放在 except
之后的 else
块中 - 如果没有错误,这就是您想要的 运行。但是在那种情况下简单地 return
会更容易:
try:
cursor_source = connect_db(source_database)
except Exception:
print("Please check your input and try again.\n")
main()
return
但是避免递归并简单地使用循环会更容易:
while True:
source_database = str(raw_input("Enter a tns name(DB_UNIQUE_NAME): ")).strip()
target_database = str(raw_input("Enter a username(OID): ")).strip()
user_password = str(getpass.getpass("Enter the password of" )).strip()
try:
cursor_source = connect_db(source_database)
except Exception:
print("Please check your input and try again.\n")
else:
break
# rest of function
我正在使用此脚本在 PostgreSQL“集群”中创建数据库和用户,然后创建存在于另一个模式中的新模式(我只复制它们的名称)。
我正在使用 Python 2.7.5,这是我的脚本:
import sys
import psycopg2
import getpass
def connect_db(database):
connection = psycopg2.connect(user="postgres",
password="mypass",
host="127.0.0.1",
port="5432",
database=str(database))
connection.autocommit = True
cursor = connection.cursor()
return cursor
def execute_query_2_select(cursor, query):
try:
cursor.execute(query)
output = cursor.fetchall()
return output
except Exception as e:
print(e)
def execute_query_2_create(cursor, query):
try:
cursor.execute(query)
except Exception as e:
print(e)
def main():
source_database = str(raw_input("Enter a tns name(DB_UNIQUE_NAME): ")).strip()
target_database = str(raw_input("Enter a username(OID): ")).strip()
user_password = str(getpass.getpass("Enter the password of" )).strip()
try:
cursor_source = connect_db(source_database)
except Exception:
print("Please check your input and try again.\n")
main()
query_2_get_schemas = "select schema_name from information_schema.schemata where schema_name not like 'pg_%' and schema_name not in ('public', 'information_schema');"
schema_template_list = execute_query_2_select(cursor_source, query_2_get_schemas)
cursor_source.close()
cursor_postgres = connect_db("postgres")
execute_query_2_create(cursor_postgres, "create user {x} with encrypted password '{y}';".format(x=target_database, y=user_password))
execute_query_2_create(cursor_postgres, "create database {x} owner {x};".format(x=target_database))
cursor_postgres.close()
cursor_target = connect_db(target_database)
for i in schema_template_list:
execute_query_2_create(cursor_target, "CREATE SCHEMA IF NOT EXISTS {x};".format(x=i[0]))
execute_query_2_create(cursor_target, "GRANT USAGE ON SCHEMA {x} TO {x};".format(x=i[0]))
execute_query_2_create(cursor_target, "GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA {x} TO {x};".format(x=i[0]))
execute_query_2_create(cursor_target, "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA {x} to {x};".format(x=i[0]))
execute_query_2_create(cursor_target, "ALTER DEFAULT PRIVILEGES IN SCHEMA {x} GRANT ALL PRIVILEGES ON TABLES TO {x};".format( x=i[0]))
execute_query_2_create(cursor_target, "ALTER DEFAULT PRIVILEGES IN SCHEMA {x} GRANT ALL PRIVILEGES ON SEQUENCES TO {x};".format( x=i[0]))
execute_query_2_create(cursor_target, "ALTER SCHEMA {x} OWNER TO {x};".format(x=i[0]))
print("Commands for schema {x} are executed!".format(x=i[0]))
cursor_target.close()
if __name__ == "__main__":
main()
因为异常块
except Exception:
print("Please check your input and try again.\n")
main()
如果用户提供了不正确的连接数据并再次输入,我将让用户返回并检查他们的输入。为了在第一次尝试时测试脚本,我提供了不正确的连接数据。然后它回到我想要它去的地方。最后,我提供了正确的信息,但这次我得到了“UnboundLocalError:局部变量 'cursor_source' 在赋值前被引用”。为什么?它在 second/later 次尝试中定义。
输出:
Enter a database name for schema pattern: asdaslkdjals
Enter a database/user name to create: asdasd
Enter the password of user asdasd
Please check your input and try again.
Enter a database name for schema pattern: test_source
Enter a database/user name to create: test_target
Enter the password of user test_target
Commands for schema test_schemaxx are executed!
Traceback (most recent call last):
File "schema.py", line 68, in <module>
main()
File "schema.py", line 44, in main
schema_template_list = execute_query_2_select(cursor_source, query_2_get_schemas)
UnboundLocalError: local variable 'cursor_source' referenced before assignment
你试过全局语句了吗? 例如,将全局放在一个循环中:
A = 20
def main():
print(‘Does Something’)
input = input(‘ variable a’s new value : ‘)
#input == 10
main()
如果您尝试访问函数内的变量,将会报错。但如果你这样做:
A = 20
def main():
global A
print(‘Does Something’)
input = input(‘ variable A’s new value : ‘)
#input == 10
main()
这将停止给出错误。
我不是 100% 了解您为什么要在本地解除绑定,但是从异常处理程序调用 main 绝对是个坏主意。
根据用户必须重试的次数,您可能会进入无限递归状态,并且可能会留下各种 half-initialized 连接。
相反,您应该在 while 循环中重试,这样您就不必退出主函数。
这是你给出的例子的递归程序流程:先是错误的输入,然后是正确的输入:
- 你打电话给
main
- 您在
try
中传递了错误的输入
- 执行
except
,再次调用main
- 你传递了很好的输入
try
执行没有问题- 函数的其余部分 运行s 和 returns
- 递归调用结束 - 回到第一次调用.
- 现在第一个
main
保持 运行ning 没有cursor_source
定义(因为try
失败)。
您基本上需要将所有代码放在 except
之后的 else
块中 - 如果没有错误,这就是您想要的 运行。但是在那种情况下简单地 return
会更容易:
try:
cursor_source = connect_db(source_database)
except Exception:
print("Please check your input and try again.\n")
main()
return
但是避免递归并简单地使用循环会更容易:
while True:
source_database = str(raw_input("Enter a tns name(DB_UNIQUE_NAME): ")).strip()
target_database = str(raw_input("Enter a username(OID): ")).strip()
user_password = str(getpass.getpass("Enter the password of" )).strip()
try:
cursor_source = connect_db(source_database)
except Exception:
print("Please check your input and try again.\n")
else:
break
# rest of function