我正在使用這個腳本在 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: local variable 'cursor_source' referenced before assignment”。為什么?它在第二次/以后的嘗試中定義。
輸出:
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
uj5u.com熱心網友回復:
這是您給出的示例的遞回程式流程:首先是錯誤輸入,然后是好的輸入:
- 你打電話
main - 你傳遞了錯誤的輸入
try - 被執行并再次
except呼叫main- 你通過了很好的輸入
- 執行
try沒有問題 - 函式的其余部分運行并回傳
- 遞回呼叫結束 -回到第一個呼叫。
- 現在第一個在沒有
main定義的情況下繼續運行(因為失敗了)。cursor_sourcetry
您需要的基本上是將所有代碼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
uj5u.com熱心網友回復:
我不是 100% 知道為什么你會在本地不受約束,但是從例外處理程式呼叫 main 絕對是個壞主意。
根據用戶必須重試的次數,您可能會進入無限遞回,并且您可能會留下各種半初始化連接。
相反,您應該在 while 回圈中進行重試,這樣您就不必退出 main 函式。
uj5u.com熱心網友回復:
您嘗試過全球宣告嗎?將全域放在一個回圈中,例如:
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()
這將停止給出錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/446216.html
標籤:Python python-2.7 例外
