Skip to content

Commit

Permalink
🐛 FIX: CREATE DATABASE with psycopg2 v2.9 (#27)
Browse files Browse the repository at this point in the history
Addresses aiidateam/aiida-core#5002:
In v2.9, the context manager opens a transaction, but databases cannot be created within them.
The fix is taken from: psycopg/psycopg2#941 (comment)
  • Loading branch information
chrisjsewell authored Aug 30, 2021
1 parent 43d8d30 commit 619d3aa
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 64 deletions.
24 changes: 9 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:

pre-commit:

runs-on: ubuntu-18.04
runs-on: ubuntu-latest
timeout-minutes: 5

steps:
Expand All @@ -17,15 +17,9 @@ jobs:
with:
python-version: 3.8

- name: Install system dependencies
run: |
sudo rm -f /etc/apt/sources.list.d/dotnetdev.list /etc/apt/sources.list.d/microsoft-prod.list
sudo apt update
sudo apt install libkrb5-dev ruby ruby-dev
- name: Install python dependencies
run: |
pip install -e .[pre-commit,testing]
pip install -e .[pre_commit,testing]
pip freeze
- name: Run pre-commit
Expand All @@ -40,7 +34,7 @@ jobs:

strategy:
matrix:
python-version: [3.5, 3.9]
python-version: [3.6, 3.9]

steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -76,14 +70,14 @@ jobs:
file: ./coverage.xml
fail_ci_if_error: true

ubuntu-apt-1604:
ubuntu-apt-1804:
# ubuntu using postgresql installed via apt (+ pgtest)
runs-on: ubuntu-16.04
runs-on: ubuntu-18.04
timeout-minutes: 5

strategy:
matrix:
python-version: [3.5]
python-version: [3.6]

steps:
- uses: actions/checkout@v2
Expand All @@ -97,9 +91,9 @@ jobs:
run: |
sudo rm -f /etc/apt/sources.list.d/dotnetdev.list /etc/apt/sources.list.d/microsoft-prod.list
sudo apt update
sudo apt install postgresql-12
sudo cat /etc/postgresql/12/main/pg_hba.conf
sudo pg_ctlcluster 12 main start
sudo apt install postgresql-10
sudo cat /etc/postgresql/10/main/pg_hba.conf
sudo pg_ctlcluster 10 main start
- name: Install pgsu
run: |
Expand Down
5 changes: 5 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ repos:
- id: mixed-line-ending
- id: trailing-whitespace

- repo: https://github.com/asottile/setup-cfg-fmt
rev: v1.17.0
hooks:
- id: setup-cfg-fmt

# yapf = yet another python formatter
- repo: https://github.com/pre-commit/mirrors-yapf
rev: v0.30.0
Expand Down
18 changes: 10 additions & 8 deletions pgsu/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,16 +250,18 @@ def _execute_psyco(command, dsn):
"""
import psycopg2 # pylint: disable=import-outside-toplevel

conn = None
output = None
with psycopg2.connect(**dsn) as conn:
try:
conn = psycopg2.connect(**dsn)
conn.autocommit = True
with conn.cursor() as cursor:
cursor.execute(command)
if cursor.description is not None:
output = cursor.fetchall()

# see http://initd.org/psycopg/docs/usage.html#with-statement
conn.close()
finally:
if conn:
conn.close()
return output


Expand Down Expand Up @@ -314,15 +316,15 @@ def _execute_su_psql(command, dsn, interactive=False, stderr=None):

database = dsn.get('database')
if database:
psql_option_str += '-d {}'.format(database)
psql_option_str += f'-d {database}'

# to do: Forward password to psql; ignore host only when the password is None. # pylint: disable=fixme
# Note: There is currently no known postgresql setup that needs this, though
# password = dsn.get('password')

host = dsn.pop('host', 'localhost')
if host and host != 'localhost':
psql_option_str += ' -h {}'.format(host)
psql_option_str += f' -h {host}'
else:
LOGGER.debug(
"Found host 'localhost' but dropping '-h localhost' option for psql "
Expand All @@ -331,7 +333,7 @@ def _execute_su_psql(command, dsn, interactive=False, stderr=None):

port = dsn.get('port')
if port:
psql_option_str += ' -p {}'.format(port)
psql_option_str += f' -p {port}'

# Note: This is *both* the UNIX user to become *and* the database user
user = dsn.get('user')
Expand Down Expand Up @@ -382,7 +384,7 @@ def escape_for_bash(str_to_escape):
string found below.
"""
escaped_quotes = str_to_escape.replace("'", """'"'"'""")
return "'{}'".format(escaped_quotes)
return f"'{escaped_quotes}'"


def unique_list(non_unique_list):
Expand Down
2 changes: 1 addition & 1 deletion pgsu/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
def run(query):
"""Execute SQL command as PostrgreSQL superuser."""
pgsu = PGSU(interactive=True, quiet=False)
click.echo('Executing query: {}'.format(query))
click.echo(f'Executing query: {query}')
dbs = pgsu.execute(query)
click.echo(pprint.pformat(dbs))
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
[build-system]
requires = ["setuptools>=46.4.0", "wheel"]
build-backend = "setuptools.build_meta"

[tool.pylint.format]
max-line-length = 120
max-args = 7
Expand Down
51 changes: 50 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,2 +1,51 @@
[metadata]
name = pgsu
version = 0.2.0
description = Connect to an existing PostgreSQL cluster as a postgres superuser and execute SQL commands.
long_description = file: README.md
long_description_content_type = text/markdown
url = https://github.com/aiidateam/pgsu
author = AiiDA Team
author_email = aiidateam@gmail.com
license = MIT
license_file = LICENSE
classifiers =
License :: OSI Approved :: MIT License
Operating System :: MacOS :: MacOS X
Operating System :: Microsoft :: Windows
Operating System :: POSIX :: Linux
Programming Language :: Python
Programming Language :: Python :: 3
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: Implementation :: CPython

[options]
packages = find:
install_requires =
click
psycopg2-binary>=2.8.3
python_requires = ~=3.6

[options.packages.find]
exclude =
test*

[options.entry_points]
console_scripts =
pgsu = pgsu.cli:run

[options.extras_require]
pre_commit =
pre-commit~=2.2
pylint~=2.5.0
testing =
pgtest>=1.3.1
pytest
pytest-cov

[coverage:run]
parallel=true
parallel = true
45 changes: 6 additions & 39 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,9 @@
# -*- coding: utf-8 -*-
"""Setup script for pgsu python package"""
import os
from setuptools import setup, find_packages
"""This file is needed for editable installs (`pip install -e .`).
THIS_FOLDER = os.path.split(os.path.abspath(__file__))[0]
Can be removed once the following is resolved
https://github.com/pypa/packaging-problems/issues/256
"""
from setuptools import setup

setup(
name='pgsu',
version='0.2.0',
description=
('Connect to an existing PostgreSQL cluster as a postgres superuser and execute SQL commands.'
),
long_description=open(os.path.join(THIS_FOLDER, 'README.md')).read(),
long_description_content_type='text/markdown',
url='https://github.com/aiidateam/pgsu',
author='AiiDA Team',
author_email='aiidateam@gmail.com',
classifiers=[
'License :: OSI Approved :: MIT License',
'Operating System :: POSIX :: Linux',
'Operating System :: MacOS :: MacOS X',
'Operating System :: Microsoft :: Windows',
'Programming Language :: Python',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
],
license='MIT',
packages=find_packages(),
install_requires=[
'psycopg2-binary>=2.8.3',
'click',
],
extras_require={
'testing': ['pytest', 'pgtest>=1.3.1', 'pytest-cov'],
# note: pre-commit hooks require python3
'pre-commit': ['pre-commit~=2.2', 'pylint~=2.5.0']
},
entry_points={'console_scripts': ['pgsu=pgsu.cli:run']})
setup()
16 changes: 16 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# To use tox, see https://tox.readthedocs.io
# Simply pip or conda install tox
# If you use conda, you may also want to install tox-conda
# then run `tox` or `tox -- {pytest args}`
# run in parallel using `tox -p`
[tox]
envlist = py38

[testenv]
usedevelop = true

[testenv:py{37,38,39}]
description = Run unit tests with this Python version
extras =
testing
commands = pytest {posargs}

0 comments on commit 619d3aa

Please sign in to comment.