Uso da biblioteca PyGreSQL de Python para se conectar a um cluster
Depois de criar um cluster de armazém de dados e usar a biblioteca de funções de terceiros PyGreSQL para se conectar ao cluster, você pode usar o Python para acessar o GaussDB(DWS) e executar várias operações em tabelas de dados
Preparações antes de se conectar a um cluster
- Um EIP foi vinculado ao cluster de armazém de dados.
- Você obteve o nome de usuário e a senha de administrador para efetuar logon no banco de dados no cluster de armazém de dados. Os algoritmos MD5 podem ser vulneráveis a ataques de colisão e não podem ser usados para verificação de senhas. Atualmente, o GaussDB(DWS) usa o design de segurança padrão. Por padrão, a verificação de senha MD5 está desabilitada, e isso pode causar falhas de conexões de clientes de código aberto. É aconselhável definir password_encryption_type como 1. Para obter detalhes, consulteModificação dos parâmetros do banco de dados.
- Por motivos de segurança, o GaussDB(DWS) não usa mais MD5 para armazenar resumos de senha por padrão. Como resultado, as unidades de código aberto e os clientes podem falhar ao se conectar ao banco de dados. Para usar o algoritmo MD5 usado em um protocolo de código aberto, você deve modificar sua política de senha e criar um novo usuário ou alterar a senha de um usuário existente.
- O banco de dados armazena o resumo de hash de senhas em vez de texto de senha. Durante a verificação de senha, o sistema compara o resumo de hash com o resumo de senha enviado pelo cliente (operações de sal estão envolvidas). Se você alterar sua política de algoritmo criptográfico, o banco de dados não poderá gerar um novo resumo de hash para sua senha existente. Para fins de conectividade, você deve alterar manualmente sua senha ou criar um novo usuário. A nova senha será criptografada usando o algoritmo de hash e armazenada para autenticação na próxima conexão.
- Você obteve o endereço de rede pública, incluindo o endereço IP e o número da porta no cluster de armazém de dados. Para mais detalhes, consulte Obtenção do endereço de conexão do cluster.
- Você instalou a biblioteca de funções de terceiros PyGreSQL.
Endereço para download: http://www.pygresql.org/download/index.html
- Para obter detalhes sobre as operações de instalação e implementação, consulte http://www.pygresql.org/contents/install.html
- No CentOS e Red Hat OS, execute o seguinte comando yum:
1yum install PyGreSQL
- PyGreSQL depende da biblioteca dinâmica libpq do PostgreSQL (versão de 32 bits ou 64 bits, o que corresponder à versão de PyGreSQL). No Linux, você pode executar o comando yum e não precisa instalar a biblioteca. Antes de usar PyGreSQL no Windows, você precisa instalar libpq de uma das seguintes maneiras:
- Instale o PostgreSQL e configure as bibliotecas dinâmicas libpq, ssl e crypto na variável de ambiente PATH.
- Instale psqlodbc e use as bibliotecas dinâmicas libpq, ssl e crypto transportadas pelo driver ODBC do PostgreSQL.
- No CentOS e Red Hat OS, execute o seguinte comando yum:
Restrições
PyGreSQL é uma interface cliente baseada em PyGreSQL, e suas funções não são totalmente suportadas pelo GaussDB(DWS). Para mais detalhes, consulte Tabela 1.
As seguintes APIs são suportadas com base em Python 3.8.5 e PyGreSQL 5.2.4.
| PyGreSQL | Sim | Observações | |
|---|---|---|---|
| Module functions and constants | connect – Open a PostgreSQL connection | Sim | - |
| get_pqlib_version – get the version of libpq | Sim | - | |
| get/set_defhost – default server host [DV] | Sim | - | |
| get/set_defport – default server port [DV] | Sim | - | |
| get/set_defopt – default connection options [DV] | Sim | - | |
| get/set_defbase – default database name [DV] | Sim | - | |
| get/set_defuser – default database user [DV] | Sim | - | |
| get/set_defpasswd – default database password [DV] | Sim | - | |
| escape_string – escape a string for use within SQL | Sim | - | |
| escape_bytea – escape binary data for use within SQL | Sim | - | |
| unescape_bytea – unescape data that has been retrieved as text | Sim | - | |
| get/set_namedresult – conversion to named tuples | Sim | - | |
| get/set_decimal – decimal type to be used for numeric values | Sim | - | |
| get/set_decimal_point – decimal mark used for monetary values | Sim | - | |
| get/set_bool – whether boolean values are returned as bool objects | Sim | - | |
| get/set_array – whether arrays are returned as list objects | Sim | - | |
| get/set_bytea_escaped – whether bytea data is returned escaped | Sim | - | |
| get/set_jsondecode – decoding JSON format | Sim | - | |
| get/set_cast_hook – fallback typecast function | Sim | - | |
| get/set_datestyle – assume a fixed date style | Sim | - | |
| get/set_typecast – custom typecasting | Sim | - | |
| cast_array/record – fast parsers for arrays and records | Sim | - | |
| Type helpers | Sim | - | |
| Module constants | Sim | - | |
| Connection – The connection object | query – execute a SQL command string | Sim | - |
| send_query - executes a SQL command string asynchronously | Sim | - | |
| query_prepared – execute a prepared statement | Sim | - | |
| prepare – create a prepared statement | Sim | - | |
| describe_prepared – describe a prepared statement | Sim | - | |
| reset – reset the connection | Sim | - | |
| poll - completes an asynchronous connection | Sim | - | |
| cancel – abandon processing of current SQL command | Sim | - | |
| close – close the database connection | Sim | - | |
| transaction – get the current transaction state | Sim | - | |
| parameter – get a current server parameter setting | Sim | - | |
| date_format – get the currently used date format | Sim | - | |
| fileno – get the socket used to connect to the database | Sim | - | |
| set_non_blocking - set the non-blocking status of the connection | Sim | - | |
| is_non_blocking - report the blocking status of the connection | Sim | - | |
| getnotify – get the last notify from the server | Não | O banco de dados não suporta listen/notify. | |
| inserttable – insert a list into a table | Sim | Use aspas duplas ("") para aspas \n no comando copy. | |
| get/set_notice_receiver – custom notice receiver | Sim | - | |
| putline – write a line to the server socket [DA] | Sim | - | |
| getline – get a line from server socket [DA] | Sim | - | |
| endcopy – synchronize client and server [DA] | Sim | - | |
| locreate – create a large object in the database [LO] | Não | Operações relacionadas a grandes objetos | |
| getlo – build a large object from given oid [LO] | Não | Operações relacionadas a grandes objetos | |
| loimport – import a file to a large object [LO] | Não | Operações relacionadas a grandes objetos | |
| Object attributes | Sim | - | |
| The DB wrapper class | Initialization | Sim | - |
| pkey – return the primary key of a table | Sim | - | |
| get_databases – get list of databases in the system | Sim | - | |
| get_relations – get list of relations in connected database | Sim | - | |
| get_tables – get list of tables in connected database | Sim | - | |
| get_attnames – get the attribute names of a table | Sim | - | |
| has_table_privilege – check table privilege | Sim | - | |
| get/set_parameter – get or set run-time parameters | Sim | - | |
| begin/commit/rollback/savepoint/release – transaction handling | Sim | - | |
| get – get a row from a database table or view | Sim | - | |
| insert – insert a row into a database table | Sim | - | |
| update – update a row in a database table | Sim | - | |
| upsert – insert a row with conflict resolution | Sim | - | |
| query – execute a SQL command string | Sim | - | |
| query_formatted – execute a formatted SQL command string | Sim | - | |
| query_prepared – execute a prepared statement | Sim | - | |
| prepare – create a prepared statement | Sim | - | |
| describe_prepared – describe a prepared statement | Sim | - | |
| delete_prepared – delete a prepared statement | Sim | - | |
| clear – clear row values in memory | Sim | - | |
| delete – delete a row from a database table | Sim | Uma tupla deve ter chave única ou chave primária. | |
| truncate – quickly empty database tables | Sim | - | |
| get_as_list/dict – read a table as a list or dictionary | Sim | - | |
| escape_literal/identifier/string/bytea – escape for SQL | Sim | - | |
| unescape_bytea – unescape data retrieved from the database | Sim | - | |
| encode/decode_json – encode and decode JSON data | Sim | - | |
| use_regtypes – determine use of regular type names | Sim | - | |
| notification_handler – create a notification handler | Não | O banco de dados não suporta listen/notify. | |
| Attributes of the DB wrapper class | Sim | - | |
| Query methods | getresult – get query values as list of tuples | Sim | - |
| dictresult/dictiter – get query values as dictionaries | Sim | - | |
| namedresult/namediter – get query values as named tuples | Sim | - | |
| scalarresult/scalariter – get query values as scalars | Sim | - | |
| one/onedict/onenamed/onescalar – get one result of a query | Sim | - | |
| single/singledict/singlenamed/singlescalar – get single result of a query | Sim | - | |
| listfields – list fields names of previous query result | Sim | - | |
| fieldname, fieldnum – field name/number conversion | Sim | - | |
| fieldinfo – detailed info about query result fields | Sim | - | |
| ntuples – return number of tuples in query object | Sim | - | |
| memsize – return number of bytes allocated by query result | Sim | - | |
| LargeObject – Large Objects | open – open a large object | Não | Operações relacionadas a grandes objetos |
| close – close a large object | Não | Operações relacionadas a grandes objetos | |
| read, write, tell, seek, unlink – file-like large object handling | Não | Operações relacionadas a grandes objetos | |
| size – get the large object size | Não | Operações relacionadas a grandes objetos | |
| export – save a large object to a file | Não | Operações relacionadas a grandes objetos | |
| Object attributes | Não | Operações relacionadas a grandes objetos | |
| The Notification Handler | Instantiating the notification handler | Não | O banco de dados não suporta listen/notify. |
| Invoking the notification handler | Não | O banco de dados não suporta listen/notify. | |
| Sending notifications | Não | O banco de dados não suporta listen/notify. | |
| Auxiliary methods | Não | O banco de dados não suporta listen/notify. | |
| pgdb | |||
| Module functions and constants | connect – Open a PostgreSQL connection | Sim | - |
| get/set/reset_typecast – Control the global typecast functions | Sim | - | |
| Module constants | Sim | - | |
| Errors raised by this module | Sim | - | |
| Connection – The connection object | close – close the connection | Sim | - |
| commit – commit the connection | Sim | - | |
| rollback – roll back the connection | Sim | - | |
| cursor – return a new cursor object | Sim | - | |
| Attributes that are not part of the standard | Sim | - | |
| Cursor – The cursor object | description – details regarding the result columns | Sim | - |
| rowcount – number of rows of the result | Sim | - | |
| close – close the cursor | Sim | - | |
| execute – execute a database operation | Sim | - | |
| executemany – execute many similar database operations | Sim | - | |
| callproc – Call a stored procedure | Sim | - | |
| fetchone – fetch next row of the query result | Sim | - | |
| fetchmany – fetch next set of rows of the query result | Sim | - | |
| fetchall – fetch all rows of the query result | Sim | - | |
| arraysize - the number of rows to fetch at a time | Sim | - | |
| Methods and attributes that are not part of the standard | Sim | - | |
| Type – Type objects and constructors | Type constructors | Sim | - |
| Type objects | Sim | - | |
Usar a biblioteca de funções de terceiros PyGreSQL para conectar-se a um cluster (Linux)
- Efetue logon no ambiente Linux como usuário root.
- Execute o seguinte comando para criar o arquivo python_dws.py:
1vi python_dws.py
Copie e cole o seguinte conteúdo no arquivo python_dws.py:
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
#!/usr/bin/env python3 # _*_ encoding:utf-8 _*_ from __future__ import print_function import pg def create_table(connection): print("Begin to create table") try: connection.query("drop table if exists test;" "create table test(id int, name text);") except pg.InternalError as e: print(e) else: print("Table created successfully") def insert_data(connection): print("Begin to insert data") try: connection.query("insert into test values(1,'number1');") connection.query("insert into test values(2,'number2');") connection.query("insert into test values(3,'number3');") except pg.InternalError as e: print(e) else: print("Insert data successfully") def update_data(connection): print("Begin to update data") try: result = connection.query("update test set name = 'numberupdated' where id=1;") print("Total number of rows updated :", result) result = connection.query("select * from test order by 1;") rows = result.getresult() for row in rows: print("id = ", row[0]) print("name = ", row[1], "\n") except pg.InternalError as e: print(e) else: print("After Update, Operation done successfully") def delete_data(connection): print("Begin to delete data") try: result = connection.query("delete from test where id=3;") print("Total number of rows deleted :", result) result = connection.query("select * from test order by 1;") rows = result.getresult() for row in rows: print("id = ", row[0]) print("name = ", row[1], "\n") except pg.InternalError as e: print(e) else: print("After Delete,Operation done successfully") def select_data(connection): print("Begin to select data") try: result = connection.query("select * from test order by 1;") rows = result.getresult() for row in rows: print("id = ", row[0]) print("name = ", row[1]) except pg.InternalError as e: print(e) print("select failed") else: print("Operation done successfully") if __name__ == '__main__': try: conn = pg.DB(host='10.154.70.231', port=8000, dbname='gaussdb', # Database to be connected user='dbadmin', passwd='password') # Database user password except pg.InternalError as ex: print(ex) print("Connect database failed") else: print("Opened database successfully") create_table(conn) insert_data(conn) select_data(conn) update_data(conn) delete_data(conn) conn.close()
Alternativamente, use a interface dbapi.
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
#!/usr/bin/python # -*- coding: UTF-8 -*- from __future__ import print_function import pg import pgdb def create_table(connection): print("Begin to create table") try: cursor = connection.cursor() cursor.execute("drop table if exists test;" "create table test(id int, name text);") connection.commit() except pg.InternalError as e: print(e) else: print("Table created successfully") cursor.close() def insert_data(connection): print("Begin to insert data") try: cursor = connection.cursor() cursor.execute("insert into test values(1,'number1');") cursor.execute("insert into test values(2,'number2');") cursor.execute("insert into test values(3,'number3');") connection.commit() except pg.InternalError as e: print(e) else: print("Insert data successfully") cursor.close() def update_data(connection): print("Begin to update data") try: cursor = connection.cursor() cursor.execute("update test set name = 'numberupdated' where id=1;") connection.commit() print("Total number of rows updated :", cursor.rowcount) cursor.execute("select * from test;") rows = cursor.fetchall() for row in rows: print("id = ", row[0]) print("name = ", row[1], "\n") except pg.InternalError as e: print(e) else: print("After Update, Operation done successfully") def delete_data(connection): print("Begin to delete data") try: cursor = connection.cursor() cursor.execute("delete from test where id=3;") connection.commit() print("Total number of rows deleted :", cursor.rowcount) cursor.execute("select * from test;") rows = cursor.fetchall() for row in rows: print("id = ", row[0]) print("name = ", row[1], "\n") except pg.InternalError as e: print(e) else: print("After Delete,Operation done successfully") def select_data(connection): print("Begin to select data") try: cursor = connection.cursor() cursor.execute("select * from test;") rows = cursor.fetchall() for row in rows: print("id = ", row[0]) print("name = ", row[1], "\n") except pg.InternalError as e: print(e) print("select failed") else: print("Operation done successfully") cursor.close() if __name__ == '__main__': try: conn = pgdb.connect(host='10.154.70.231', port='8000', database='gaussdb', # Database to be connected user='dbadmin', password='password') # Database user password except pg.InternalError as ex: print(ex) print("Connect database failed") else: print("Opened database successfully") create_table(conn) insert_data(conn) select_data(conn) update_data(conn) delete_data(conn) conn.close()
- Altere o endereço de rede pública, o número da porta do cluster, o nome do banco de dados, o nome do usuário do banco de dados e a senha do banco de dados no arquivo python_dws.py com base nas informações reais do cluster.
A API de PyGreSQL não fornece o recurso de repetição de conexão. Você precisa implementar o processamento de nova tentativa no código de serviço.
1 2 3 4 5
conn = pgdb.connect(host='10.154.70.231', port='8000', database='gaussdb', # Database to be connected user='dbadmin', password='password') # Database user password
- Execute o seguinte comando para se conectar ao cluster usando a biblioteca de funções de terceiros PyGreSQL:
1python python_dws.py
Usar a biblioteca de funções de terceiros PyGreSQL para conectar-se a um cluster (Windows)
- No sistema operacional Windows, clique no botão Start, digite cmd na caixa de pesquisa e clique em cmd.exe na lista de resultados para abrir a interface de linha de comando (CLI).
- Na CLI, execute o seguinte comando para criar o arquivo python_dws.py:
1type nul> python_dws.py
Copie e cole o seguinte conteúdo no arquivo python_dws.py:
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
#!/usr/bin/env python3 # _*_ encoding:utf-8 _*_ from __future__ import print_function import pg def create_table(connection): print("Begin to create table") try: connection.query("drop table if exists test;" "create table test(id int, name text);") except pg.InternalError as e: print(e) else: print("Table created successfully") def insert_data(connection): print("Begin to insert data") try: connection.query("insert into test values(1,'number1');") connection.query("insert into test values(2,'number2');") connection.query("insert into test values(3,'number3');") except pg.InternalError as e: print(e) else: print("Insert data successfully") def update_data(connection): print("Begin to update data") try: result = connection.query("update test set name = 'numberupdated' where id=1;") print("Total number of rows updated :", result) result = connection.query("select * from test order by 1;") rows = result.getresult() for row in rows: print("id = ", row[0]) print("name = ", row[1], "\n") except pg.InternalError as e: print(e) else: print("After Update, Operation done successfully") def delete_data(connection): print("Begin to delete data") try: result = connection.query("delete from test where id=3;") print("Total number of rows deleted :", result) result = connection.query("select * from test order by 1;") rows = result.getresult() for row in rows: print("id = ", row[0]) print("name = ", row[1], "\n") except pg.InternalError as e: print(e) else: print("After Delete,Operation done successfully") def select_data(connection): print("Begin to select data") try: result = connection.query("select * from test order by 1;") rows = result.getresult() for row in rows: print("id = ", row[0]) print("name = ", row[1]) except pg.InternalError as e: print(e) print("select failed") else: print("Operation done successfully") if __name__ == '__main__': try: conn = pg.DB(host='10.154.70.231', port=8000, dbname='gaussdb', # Database to be connected user='dbadmin', passwd='password') # Database user password except pg.InternalError as ex: print(ex) print("Connect database failed") else: print("Opened database successfully") create_table(conn) insert_data(conn) select_data(conn) update_data(conn) delete_data(conn) conn.close()
Alternativamente, use a interface dbapi.
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
#!/usr/bin/python # -*- coding: UTF-8 -*- from __future__ import print_function import pg import pgdb def create_table(connection): print("Begin to create table") try: cursor = connection.cursor() cursor.execute("drop table if exists test;" "create table test(id int, name text);") connection.commit() except pg.InternalError as e: print(e) else: print("Table created successfully") cursor.close() def insert_data(connection): print("Begin to insert data") try: cursor = connection.cursor() cursor.execute("insert into test values(1,'number1');") cursor.execute("insert into test values(2,'number2');") cursor.execute("insert into test values(3,'number3');") connection.commit() except pg.InternalError as e: print(e) else: print("Insert data successfully") cursor.close() def update_data(connection): print("Begin to update data") try: cursor = connection.cursor() cursor.execute("update test set name = 'numberupdated' where id=1;") connection.commit() print("Total number of rows updated :", cursor.rowcount) cursor.execute("select * from test;") rows = cursor.fetchall() for row in rows: print("id = ", row[0]) print("name = ", row[1], "\n") except pg.InternalError as e: print(e) else: print("After Update, Operation done successfully") def delete_data(connection): print("Begin to delete data") try: cursor = connection.cursor() cursor.execute("delete from test where id=3;") connection.commit() print("Total number of rows deleted :", cursor.rowcount) cursor.execute("select * from test;") rows = cursor.fetchall() for row in rows: print("id = ", row[0]) print("name = ", row[1], "\n") except pg.InternalError as e: print(e) else: print("After Delete,Operation done successfully") def select_data(connection): print("Begin to select data") try: cursor = connection.cursor() cursor.execute("select * from test;") rows = cursor.fetchall() for row in rows: print("id = ", row[0]) print("name = ", row[1], "\n") except pg.InternalError as e: print(e) print("select failed") else: print("Operation done successfully") cursor.close() if __name__ == '__main__': try: conn = pgdb.connect(host='10.154.70.231', port='8000', database='gaussdb', # Database to be connected user='dbadmin', password='password') # Database user password except pg.InternalError as ex: print(ex) print("Connect database failed") else: print("Opened database successfully") create_table(conn) insert_data(conn) select_data(conn) update_data(conn) delete_data(conn) conn.close()
- Altere o endereço de rede pública, o número da porta do cluster, o nome do banco de dados, o nome do usuário do banco de dados e a senha do banco de dados no arquivo python_dws.py com base nas informações reais do cluster.
A API de PyGreSQL não fornece o recurso de repetição de conexão. Você precisa implementar o processamento de nova tentativa no código de serviço.
1 2 3 4 5
conn = pgdb.connect(host='10.154.70.231', port='8000', database='gaussdb', # Database to be connected user='dbadmin', password='password') # Database user password
- Execute o seguinte comando para se conectar ao cluster usando a biblioteca de funções de terceiros PyGreSQL:
1python python_dws.py