Desenvolvo uma agenda telefônica em Tkinter com o banco de dados sqlite3.
Ao pressionar o botão gravar, quando o contato é novo, um novo registro deve ser gerado no banco de dados.
Como posso fazer para verificar se o registro já existe e gravar ou atualizar, caso já exista, sem ter que recorrer a uma gambiarra de código com múltiplas consultas e ifs?
- Home
- >
- Fórum
- >
- Profissional
- >
- Programação, Sc...
- >
- Consulta SQLite
SQLite permite indexação, portanto basta usar chaves adequadas e como TCL/Tk não é minha praia, fiz uma pesquisa rápida e confirmei que existe:
try { SQL_INSERT } catch ( SQL_ERRO ) { SQL_UPDATE } finally { OPCIONAL }
[
]'s
Crie a tabela com uma chave primária. E aí você tenta fazer a inserção dentro de um try. Se o adaptador levantar a exceção IntegrityError você captura e trata. Olha o exemplo do manual:
import sqlite3
con = sqlite3.connect(":memory:"
con.execute("create table person (id integer primary key, firstname varchar unique)"
# Successful, con.commit() is called automatically afterwards
with con:
con.execute("insert into person(firstname) values (?)", ("Joe",))
# con.rollback() is called after the with block finishes with an exception, the
# exception is still raised and must be catched
try:
with con:
con.execute("insert into person(firstname) values (?)", ("Joe",))
except sqlite3.IntegrityError:
print "couldn't add Joe twice"
Valeu. Propagando reputações...
Outra forma quando não há a possibilidade de criação de chaves primárias ou o uso de índices para verificação, é possível fazer um SELECT antes de inserir, se retornar UM registro que seja ou vários, quer dizer que já existe determinado registro, e então basta barrar, dizendo que já existem registros com essas informações.
Abraço
Delphing disse: Outra forma quando não há a possibilidade de criação de chaves primárias ou o uso de índices para verificação, é possível fazer um SELECT antes de inserir, se retornar UM registro que seja ou vários, quer dizer que já existe determinado registro, e então basta barrar, dizendo que já existem registros com essas informações.
Abraço
Delphing, é exatamente isso que eu quero evitar.
Uma pergnta, a declaração `with con` no exemplo trata a conexão como um cursor, executando consultas. É algum tipo de mágia ou o Python tem fnções 'built-in' na declaração with para o módulo sqlite3?
O with executa o método __enter__ do objeto con e no fim do bloco executa o método __exit__ do mesmo objeto
Nesse caso, todos os módulos escritos desde a introdução da declaração `with`, salvo engano após a versão 2.5, devem conter os atributos __enter__() e __exit__() correto?
Eu acredito que sim mesmo que estes métodos não façam nada.
Detalhe: não é o módulo que define os métodos __enter__ e __exit__ e sim a classe. Por exemplo a classe Connection do sqlite3:
>>> dir(sqlite3.Connection)
['DataError', 'DatabaseError', 'Error', 'IntegrityError', 'InterfaceError', 'InternalError', 'NotSupportedError', 'OperationalError', 'ProgrammingError', 'Warning', '__call__', '__class__', '__delattr__', '__doc__', '__enter__', '__exit__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'commit', 'create_aggregate', 'create_collation', 'create_function', 'cursor', 'execute', 'executemany', 'executescript', 'interrupt', 'isolation_level', 'iterdump', 'rollback', 'row_factory', 'set_authorizer', 'set_progress_handler', 'text_factory', 'total_changes']
Já resolvi meu problema. Vou dar uma aprofundada em `with` e aproveitar para ver algumas coisas em Python que ainda desconheco como os gerenciadores de contexto e decoradores.
Muito grato.