mirror of
https://github.com/dbcli/pgcli
synced 2024-05-31 01:17:54 +00:00
Merge branch 'master' into master
This commit is contained in:
commit
0643fd6534
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
@ -5,5 +5,5 @@
|
||||||
|
|
||||||
## Checklist
|
## Checklist
|
||||||
<!--- We appreciate your help and want to give you credit. Please take a moment to put an `x` in the boxes below as you complete them. -->
|
<!--- We appreciate your help and want to give you credit. Please take a moment to put an `x` in the boxes below as you complete them. -->
|
||||||
- [ ] I've added this contribution to the `changelog.md`.
|
- [ ] I've added this contribution to the `changelog.rst`.
|
||||||
- [ ] I've added my name to the `AUTHORS` file (or it's already there).
|
- [ ] I've added my name to the `AUTHORS` file (or it's already there).
|
||||||
|
|
|
@ -8,6 +8,7 @@ python:
|
||||||
install:
|
install:
|
||||||
- pip install .
|
- pip install .
|
||||||
- pip install -r requirements-dev.txt
|
- pip install -r requirements-dev.txt
|
||||||
|
- pip install keyrings.alt>=3.1
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- set -e
|
- set -e
|
||||||
|
|
2
AUTHORS
2
AUTHORS
|
@ -76,6 +76,8 @@ Contributors:
|
||||||
* Pierre Giraud
|
* Pierre Giraud
|
||||||
* Andrew Kuchling
|
* Andrew Kuchling
|
||||||
* Dan Clark
|
* Dan Clark
|
||||||
|
* Catherine Devlin
|
||||||
|
* Jason Ribeiro
|
||||||
|
|
||||||
|
|
||||||
Creator:
|
Creator:
|
||||||
|
|
|
@ -148,8 +148,8 @@ To see stdout/stderr, use the following command:
|
||||||
$ behave --no-capture
|
$ behave --no-capture
|
||||||
|
|
||||||
|
|
||||||
PEP8 checks
|
PEP8 checks (lint)
|
||||||
-----------
|
-----------------_
|
||||||
|
|
||||||
When you submit a PR, the changeset is checked for pep8 compliance using
|
When you submit a PR, the changeset is checked for pep8 compliance using
|
||||||
`pep8radius <https://github.com/hayd/pep8radius>`_. If you see a build failing because
|
`pep8radius <https://github.com/hayd/pep8radius>`_. If you see a build failing because
|
||||||
|
@ -158,7 +158,7 @@ of these checks, install pep8radius and apply style fixes:
|
||||||
::
|
::
|
||||||
|
|
||||||
$ pip install pep8radius
|
$ pip install pep8radius
|
||||||
$ pep8radius --docformatter --diff # view a diff of proposed fixes
|
$ pep8radius master --docformatter --diff # view a diff of proposed fixes
|
||||||
$ pep8radius --docformatter --in-place # apply the fixes
|
$ pep8radius master --docformatter --in-place # apply the fixes
|
||||||
|
|
||||||
Then commit and push the fixes.
|
Then commit and push the fixes.
|
||||||
|
|
|
@ -48,7 +48,7 @@ Usage
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
$ pgcli postgresql://[user[:password]@][netloc][:port][/dbname]
|
$ pgcli postgresql://[user[:password]@][netloc][:port][/dbname][?extra=value[&other=other-value]]
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ Examples:
|
||||||
|
|
||||||
$ pgcli local_database
|
$ pgcli local_database
|
||||||
|
|
||||||
$ pgcli postgres://amjith:pa$$w0rd@example.com:5432/app_db
|
$ pgcli postgres://amjith:pa$$w0rd@example.com:5432/app_db?sslmode=verify-ca&sslrootcert=/myrootcert
|
||||||
|
|
||||||
Features
|
Features
|
||||||
--------
|
--------
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
Upcoming:
|
Upcoming:
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
Features:
|
||||||
|
---------
|
||||||
|
* Add quit commands to the completion menu. (Thanks: `Jason Ribeiro`_)
|
||||||
|
* Add table formats to ``\T`` completion. (Thanks: `Jason Ribeiro`_)
|
||||||
|
|
||||||
Internal changes:
|
Internal changes:
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
@ -8,6 +13,11 @@ Internal changes:
|
||||||
* Add ``application_name`` to help identify pgcli connection to database (issue #868) (Thanks: `François Pietka`_)
|
* Add ``application_name`` to help identify pgcli connection to database (issue #868) (Thanks: `François Pietka`_)
|
||||||
* Ported Destructive Warning from mycli.
|
* Ported Destructive Warning from mycli.
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
----------
|
||||||
|
* Disable pager when using \watch (#837). (Thanks: `Jason Ribeiro`_)
|
||||||
|
* Don't offer to reconnect when we can't change a param in realtime (#807). (Thanks: `Amjith Ramanujam`_)
|
||||||
|
|
||||||
1.9.1:
|
1.9.1:
|
||||||
======
|
======
|
||||||
|
|
||||||
|
@ -746,6 +756,7 @@ Bug Fixes:
|
||||||
----------
|
----------
|
||||||
* Fix the broken behavior of \d+. (Thanks: https://github.com/macobo)
|
* Fix the broken behavior of \d+. (Thanks: https://github.com/macobo)
|
||||||
* Fix a crash during auto-completion. (Thanks: https://github.com/Erethon)
|
* Fix a crash during auto-completion. (Thanks: https://github.com/Erethon)
|
||||||
|
* Avoid losing pre_run_callables on error in editing. (Thanks: https://github.com/catherinedevlin)
|
||||||
|
|
||||||
Improvements:
|
Improvements:
|
||||||
-------------
|
-------------
|
||||||
|
@ -814,3 +825,4 @@ Improvements:
|
||||||
.. _`Isank`: https://github.com/isank
|
.. _`Isank`: https://github.com/isank
|
||||||
.. _`Bojan Delić`: https://github.com/delicb
|
.. _`Bojan Delić`: https://github.com/delicb
|
||||||
.. _`Frederic Aoustin`: https://github.com/fraoustin
|
.. _`Frederic Aoustin`: https://github.com/fraoustin
|
||||||
|
.. _`Jason Ribeiro`: https://github.com/jrib
|
||||||
|
|
|
@ -40,6 +40,7 @@ from pygments.token import Token
|
||||||
|
|
||||||
from pgspecial.main import (PGSpecial, NO_QUERY, PAGER_OFF)
|
from pgspecial.main import (PGSpecial, NO_QUERY, PAGER_OFF)
|
||||||
import pgspecial as special
|
import pgspecial as special
|
||||||
|
import keyring
|
||||||
from .pgcompleter import PGCompleter
|
from .pgcompleter import PGCompleter
|
||||||
from .pgtoolbar import create_toolbar_tokens_func
|
from .pgtoolbar import create_toolbar_tokens_func
|
||||||
from .pgstyle import style_factory, style_factory_output
|
from .pgstyle import style_factory, style_factory_output
|
||||||
|
@ -91,6 +92,10 @@ OutputSettings.__new__.__defaults__ = (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class PgCliQuitError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class PGCli(object):
|
class PGCli(object):
|
||||||
|
|
||||||
default_prompt = '\\u@\\h:\\d> '
|
default_prompt = '\\u@\\h:\\d> '
|
||||||
|
@ -202,6 +207,9 @@ class PGCli(object):
|
||||||
self.eventloop = create_eventloop()
|
self.eventloop = create_eventloop()
|
||||||
self.cli = None
|
self.cli = None
|
||||||
|
|
||||||
|
def quit(self):
|
||||||
|
raise PgCliQuitError
|
||||||
|
|
||||||
def register_special_commands(self):
|
def register_special_commands(self):
|
||||||
|
|
||||||
self.pgspecial.register(
|
self.pgspecial.register(
|
||||||
|
@ -211,6 +219,12 @@ class PGCli(object):
|
||||||
refresh_callback = lambda: self.refresh_completions(
|
refresh_callback = lambda: self.refresh_completions(
|
||||||
persist_priorities='all')
|
persist_priorities='all')
|
||||||
|
|
||||||
|
self.pgspecial.register(self.quit, '\\q', '\\q',
|
||||||
|
'Quit pgcli.', arg_type=NO_QUERY, case_sensitive=True,
|
||||||
|
aliases=(':q',))
|
||||||
|
self.pgspecial.register(self.quit, 'quit', 'quit',
|
||||||
|
'Quit pgcli.', arg_type=NO_QUERY, case_sensitive=False,
|
||||||
|
aliases=('exit',))
|
||||||
self.pgspecial.register(refresh_callback, '\\#', '\\#',
|
self.pgspecial.register(refresh_callback, '\\#', '\\#',
|
||||||
'Refresh auto-completions.', arg_type=NO_QUERY)
|
'Refresh auto-completions.', arg_type=NO_QUERY)
|
||||||
self.pgspecial.register(refresh_callback, '\\refresh', '\\refresh',
|
self.pgspecial.register(refresh_callback, '\\refresh', '\\refresh',
|
||||||
|
@ -367,7 +381,7 @@ class PGCli(object):
|
||||||
user=fixup_possible_percent_encoding(uri.username),
|
user=fixup_possible_percent_encoding(uri.username),
|
||||||
port=fixup_possible_percent_encoding(uri.port),
|
port=fixup_possible_percent_encoding(uri.port),
|
||||||
passwd=fixup_possible_percent_encoding(uri.password))
|
passwd=fixup_possible_percent_encoding(uri.password))
|
||||||
# Deal with extra params e.g. ?sslmode=verify-ca&ssl-cert=/mycert
|
# Deal with extra params e.g. ?sslmode=verify-ca&sslrootcert=/myrootcert
|
||||||
if uri.query:
|
if uri.query:
|
||||||
arguments = dict(
|
arguments = dict(
|
||||||
{k: v for k, (v,) in parse_qs(uri.query).items()},
|
{k: v for k, (v,) in parse_qs(uri.query).items()},
|
||||||
|
@ -391,6 +405,11 @@ class PGCli(object):
|
||||||
if not self.force_passwd_prompt and not passwd:
|
if not self.force_passwd_prompt and not passwd:
|
||||||
passwd = os.environ.get('PGPASSWORD', '')
|
passwd = os.environ.get('PGPASSWORD', '')
|
||||||
|
|
||||||
|
# Find password from store
|
||||||
|
key = '%s@%s' % (user, host)
|
||||||
|
if not passwd:
|
||||||
|
passwd = keyring.get_password('pgcli', key)
|
||||||
|
|
||||||
# Prompt for a password immediately if requested via the -W flag. This
|
# Prompt for a password immediately if requested via the -W flag. This
|
||||||
# avoids wasting time trying to connect to the database and catching a
|
# avoids wasting time trying to connect to the database and catching a
|
||||||
# no-password exception.
|
# no-password exception.
|
||||||
|
@ -412,6 +431,8 @@ class PGCli(object):
|
||||||
try:
|
try:
|
||||||
pgexecute = PGExecute(database, user, passwd, host, port, dsn,
|
pgexecute = PGExecute(database, user, passwd, host, port, dsn,
|
||||||
application_name='pgcli', **kwargs)
|
application_name='pgcli', **kwargs)
|
||||||
|
if passwd:
|
||||||
|
keyring.set_password('pgcli', key, passwd)
|
||||||
except (OperationalError, InterfaceError) as e:
|
except (OperationalError, InterfaceError) as e:
|
||||||
if ('no password supplied' in utf8tounicode(e.args[0]) and
|
if ('no password supplied' in utf8tounicode(e.args[0]) and
|
||||||
auto_passwd_prompt):
|
auto_passwd_prompt):
|
||||||
|
@ -421,6 +442,8 @@ class PGCli(object):
|
||||||
pgexecute = PGExecute(database, user, passwd, host, port,
|
pgexecute = PGExecute(database, user, passwd, host, port,
|
||||||
dsn, application_name='pgcli',
|
dsn, application_name='pgcli',
|
||||||
**kwargs)
|
**kwargs)
|
||||||
|
if passwd:
|
||||||
|
keyring.set_password('pgcli', key, passwd)
|
||||||
else:
|
else:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
@ -449,19 +472,22 @@ class PGCli(object):
|
||||||
# It's internal api of prompt_toolkit that may change. This was added to fix #668.
|
# It's internal api of prompt_toolkit that may change. This was added to fix #668.
|
||||||
# We may find a better way to do it in the future.
|
# We may find a better way to do it in the future.
|
||||||
saved_callables = cli.application.pre_run_callables
|
saved_callables = cli.application.pre_run_callables
|
||||||
while special.editor_command(document.text):
|
try:
|
||||||
filename = special.get_filename(document.text)
|
while special.editor_command(document.text):
|
||||||
query = (special.get_editor_query(document.text) or
|
filename = special.get_filename(document.text)
|
||||||
self.get_last_query())
|
query = (special.get_editor_query(document.text) or
|
||||||
sql, message = special.open_external_editor(filename, sql=query)
|
self.get_last_query())
|
||||||
if message:
|
sql, message = special.open_external_editor(
|
||||||
# Something went wrong. Raise an exception and bail.
|
filename, sql=query)
|
||||||
raise RuntimeError(message)
|
if message:
|
||||||
cli.current_buffer.document = Document(sql, cursor_position=len(sql))
|
# Something went wrong. Raise an exception and bail.
|
||||||
cli.application.pre_run_callables = []
|
raise RuntimeError(message)
|
||||||
document = cli.run()
|
cli.current_buffer.document = Document(sql,
|
||||||
continue
|
cursor_position=len(sql))
|
||||||
cli.application.pre_run_callables = saved_callables
|
cli.application.pre_run_callables = []
|
||||||
|
document = cli.run()
|
||||||
|
finally:
|
||||||
|
cli.application.pre_run_callables = saved_callables
|
||||||
return document
|
return document
|
||||||
|
|
||||||
def execute_command(self, text, query):
|
def execute_command(self, text, query):
|
||||||
|
@ -489,6 +515,8 @@ class PGCli(object):
|
||||||
logger.error("sql: %r, error: %r", text, e)
|
logger.error("sql: %r, error: %r", text, e)
|
||||||
logger.error("traceback: %r", traceback.format_exc())
|
logger.error("traceback: %r", traceback.format_exc())
|
||||||
self._handle_server_closed_connection()
|
self._handle_server_closed_connection()
|
||||||
|
except PgCliQuitError as e:
|
||||||
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("sql: %r, error: %r", text, e)
|
logger.error("sql: %r, error: %r", text, e)
|
||||||
logger.error("traceback: %r", traceback.format_exc())
|
logger.error("traceback: %r", traceback.format_exc())
|
||||||
|
@ -555,13 +583,6 @@ class PGCli(object):
|
||||||
while True:
|
while True:
|
||||||
document = self.cli.run()
|
document = self.cli.run()
|
||||||
|
|
||||||
# The reason we check here instead of inside the pgexecute is
|
|
||||||
# because we want to raise the Exit exception which will be
|
|
||||||
# caught by the try/except block that wraps the pgexecute.run()
|
|
||||||
# statement.
|
|
||||||
if quit_command(document.text):
|
|
||||||
raise EOFError
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
document = self.handle_editor_command(self.cli, document)
|
document = self.handle_editor_command(self.cli, document)
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
|
@ -573,15 +594,19 @@ class PGCli(object):
|
||||||
# Initialize default metaquery in case execution fails
|
# Initialize default metaquery in case execution fails
|
||||||
query = MetaQuery(query=document.text, successful=False)
|
query = MetaQuery(query=document.text, successful=False)
|
||||||
|
|
||||||
watch_command, timing = special.get_watch_command(document.text)
|
self.watch_command, timing = special.get_watch_command(
|
||||||
if watch_command:
|
document.text)
|
||||||
while watch_command:
|
if self.watch_command:
|
||||||
|
while self.watch_command:
|
||||||
try:
|
try:
|
||||||
query = self.execute_command(watch_command, query)
|
query = self.execute_command(
|
||||||
click.echo('Waiting for {0} seconds before repeating'.format(timing))
|
self.watch_command, query)
|
||||||
|
click.echo(
|
||||||
|
'Waiting for {0} seconds before repeating'
|
||||||
|
.format(timing))
|
||||||
sleep(timing)
|
sleep(timing)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
watch_command = None
|
self.watch_command = None
|
||||||
else:
|
else:
|
||||||
query = self.execute_command(document.text, query)
|
query = self.execute_command(document.text, query)
|
||||||
|
|
||||||
|
@ -593,7 +618,7 @@ class PGCli(object):
|
||||||
|
|
||||||
self.query_history.append(query)
|
self.query_history.append(query)
|
||||||
|
|
||||||
except EOFError:
|
except PgCliQuitError:
|
||||||
if not self.less_chatty:
|
if not self.less_chatty:
|
||||||
print ('Goodbye!')
|
print ('Goodbye!')
|
||||||
|
|
||||||
|
@ -849,7 +874,7 @@ class PGCli(object):
|
||||||
return self.query_history[-1][0] if self.query_history else None
|
return self.query_history[-1][0] if self.query_history else None
|
||||||
|
|
||||||
def echo_via_pager(self, text, color=None):
|
def echo_via_pager(self, text, color=None):
|
||||||
if self.pgspecial.pager_config == PAGER_OFF:
|
if self.pgspecial.pager_config == PAGER_OFF or self.watch_command:
|
||||||
click.echo(text, color=color)
|
click.echo(text, color=color)
|
||||||
else:
|
else:
|
||||||
click.echo_via_pager(text, color)
|
click.echo_via_pager(text, color)
|
||||||
|
@ -1044,13 +1069,6 @@ def is_select(status):
|
||||||
return status.split(None, 1)[0].lower() == 'select'
|
return status.split(None, 1)[0].lower() == 'select'
|
||||||
|
|
||||||
|
|
||||||
def quit_command(sql):
|
|
||||||
return (sql.strip().lower() == 'exit'
|
|
||||||
or sql.strip().lower() == 'quit'
|
|
||||||
or sql.strip() == r'\q'
|
|
||||||
or sql.strip() == ':q')
|
|
||||||
|
|
||||||
|
|
||||||
def exception_formatter(e):
|
def exception_formatter(e):
|
||||||
return click.style(utf8tounicode(str(e)), fg='red')
|
return click.style(utf8tounicode(str(e)), fg='red')
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ Schema.__new__.__defaults__ = (False,)
|
||||||
# used to ensure that the alias we suggest is unique
|
# used to ensure that the alias we suggest is unique
|
||||||
FromClauseItem = namedtuple('FromClauseItem', 'schema table_refs local_tables')
|
FromClauseItem = namedtuple('FromClauseItem', 'schema table_refs local_tables')
|
||||||
Table = namedtuple('Table', ['schema', 'table_refs', 'local_tables'])
|
Table = namedtuple('Table', ['schema', 'table_refs', 'local_tables'])
|
||||||
|
TableFormat = namedtuple('TableFormat', [])
|
||||||
View = namedtuple('View', ['schema', 'table_refs'])
|
View = namedtuple('View', ['schema', 'table_refs'])
|
||||||
# JoinConditions are suggested after ON, e.g. 'foo.barid = bar.barid'
|
# JoinConditions are suggested after ON, e.g. 'foo.barid = bar.barid'
|
||||||
JoinCondition = namedtuple('JoinCondition', ['table_refs', 'parent'])
|
JoinCondition = namedtuple('JoinCondition', ['table_refs', 'parent'])
|
||||||
|
@ -252,6 +253,9 @@ def suggest_special(text):
|
||||||
if cmd in ('\\c', '\\connect'):
|
if cmd in ('\\c', '\\connect'):
|
||||||
return (Database(),)
|
return (Database(),)
|
||||||
|
|
||||||
|
if cmd == '\\T':
|
||||||
|
return (TableFormat(),)
|
||||||
|
|
||||||
if cmd == '\\dn':
|
if cmd == '\\dn':
|
||||||
return (Schema(),)
|
return (Schema(),)
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,15 @@ import re
|
||||||
from itertools import count, repeat, chain
|
from itertools import count, repeat, chain
|
||||||
import operator
|
import operator
|
||||||
from collections import namedtuple, defaultdict, OrderedDict
|
from collections import namedtuple, defaultdict, OrderedDict
|
||||||
|
from cli_helpers.tabular_output import TabularOutputFormatter
|
||||||
from pgspecial.namedqueries import NamedQueries
|
from pgspecial.namedqueries import NamedQueries
|
||||||
from prompt_toolkit.completion import Completer, Completion
|
from prompt_toolkit.completion import Completer, Completion
|
||||||
from prompt_toolkit.contrib.completers import PathCompleter
|
from prompt_toolkit.contrib.completers import PathCompleter
|
||||||
from prompt_toolkit.document import Document
|
from prompt_toolkit.document import Document
|
||||||
from .packages.sqlcompletion import (FromClauseItem,
|
from .packages.sqlcompletion import (
|
||||||
suggest_type, Special, Database, Schema, Table, Function, Column, View,
|
FromClauseItem, suggest_type, Special, Database, Schema, Table,
|
||||||
Keyword, NamedQuery, Datatype, Alias, Path, JoinCondition, Join)
|
TableFormat, Function, Column, View, Keyword, NamedQuery,
|
||||||
|
Datatype, Alias, Path, JoinCondition, Join)
|
||||||
from .packages.parseutils.meta import ColumnMetadata, ForeignKey
|
from .packages.parseutils.meta import ColumnMetadata, ForeignKey
|
||||||
from .packages.parseutils.utils import last_word
|
from .packages.parseutils.utils import last_word
|
||||||
from .packages.parseutils.tables import TableReference
|
from .packages.parseutils.tables import TableReference
|
||||||
|
@ -321,7 +323,8 @@ class PGCompleter(Completer):
|
||||||
return []
|
return []
|
||||||
prio_order = [
|
prio_order = [
|
||||||
'keyword', 'function', 'view', 'table', 'datatype', 'database',
|
'keyword', 'function', 'view', 'table', 'datatype', 'database',
|
||||||
'schema', 'column', 'table alias', 'join', 'name join', 'fk join'
|
'schema', 'column', 'table alias', 'join', 'name join', 'fk join',
|
||||||
|
'table format'
|
||||||
]
|
]
|
||||||
type_priority = prio_order.index(meta) if meta in prio_order else -1
|
type_priority = prio_order.index(meta) if meta in prio_order else -1
|
||||||
text = last_word(text, include='most_punctuations').lower()
|
text = last_word(text, include='most_punctuations').lower()
|
||||||
|
@ -778,6 +781,9 @@ class PGCompleter(Completer):
|
||||||
tables = [self._make_cand(t, alias, suggestion) for t in tables]
|
tables = [self._make_cand(t, alias, suggestion) for t in tables]
|
||||||
return self.find_matches(word_before_cursor, tables, meta='table')
|
return self.find_matches(word_before_cursor, tables, meta='table')
|
||||||
|
|
||||||
|
def get_table_formats(self, _, word_before_cursor):
|
||||||
|
formats = TabularOutputFormatter().supported_formats
|
||||||
|
return self.find_matches(word_before_cursor, formats, meta='table format')
|
||||||
|
|
||||||
def get_view_matches(self, suggestion, word_before_cursor, alias=False):
|
def get_view_matches(self, suggestion, word_before_cursor, alias=False):
|
||||||
views = self.populate_schema_objects(suggestion.schema, 'views')
|
views = self.populate_schema_objects(suggestion.schema, 'views')
|
||||||
|
@ -861,6 +867,7 @@ class PGCompleter(Completer):
|
||||||
Function: get_function_matches,
|
Function: get_function_matches,
|
||||||
Schema: get_schema_matches,
|
Schema: get_schema_matches,
|
||||||
Table: get_table_matches,
|
Table: get_table_matches,
|
||||||
|
TableFormat: get_table_formats,
|
||||||
View: get_view_matches,
|
View: get_view_matches,
|
||||||
Alias: get_alias_matches,
|
Alias: get_alias_matches,
|
||||||
Database: get_database_matches,
|
Database: get_database_matches,
|
||||||
|
|
|
@ -346,7 +346,8 @@ class PGExecute(object):
|
||||||
"""
|
"""
|
||||||
return (isinstance(e, psycopg2.OperationalError) and
|
return (isinstance(e, psycopg2.OperationalError) and
|
||||||
(not e.pgcode or
|
(not e.pgcode or
|
||||||
psycopg2.errorcodes.lookup(e.pgcode) != 'LOCK_NOT_AVAILABLE'))
|
psycopg2.errorcodes.lookup(e.pgcode) not in
|
||||||
|
('LOCK_NOT_AVAILABLE', 'CANT_CHANGE_RUNTIME_PARAM')))
|
||||||
|
|
||||||
def execute_normal_sql(self, split_sql):
|
def execute_normal_sql(self, split_sql):
|
||||||
"""Returns tuple (title, rows, headers, status)"""
|
"""Returns tuple (title, rows, headers, status)"""
|
||||||
|
|
Loading…
Reference in New Issue
Block a user