Skip to content

Commit

Permalink
i
Browse files Browse the repository at this point in the history
  • Loading branch information
tlocke committed Mar 29, 2024
1 parent 28fabee commit 9bba90d
Showing 1 changed file with 54 additions and 70 deletions.
124 changes: 54 additions & 70 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1305,136 +1305,120 @@ possible to change the default mapping using adapters (see the examples).
| tuple | composite type | Only from Python to PostgreSQL |


## Theory Of Operation

Theory Of Operation
-------------------

A concept is tolerated inside the microkernel only if moving it outside the kernel,
i.e., permitting competing implementations, would prevent the implementation of the
system's required functionality.

-- Jochen Liedtke, Liedtke's minimality principle
> A concept is tolerated inside the microkernel only if moving it outside the kernel,
> i.e., permitting competing implementations, would prevent the implementation of the
> system's required functionality.
>
> -- Jochen Liedtke, Liedtke's minimality principle
pg8000 is designed to be used with one thread per connection.

Pg8000 communicates with the database using the `PostgreSQL Frontend/Backend Protocol
<https://www.postgresql.org/docs/current/protocol.html>`_ (FEBE). If a query has no
Pg8000 communicates with the database using the [PostgreSQL Frontend/Backend Protocol]
(https://www.postgresql.org/docs/current/protocol.html) (FEBE). If a query has no
parameters, pg8000 uses the 'simple query protocol'. If a query does have parameters,
pg8000 uses the 'extended query protocol' with unnamed prepared statements. The steps
for a query with parameters are:

1. Query comes in.

#. Send a PARSE message to the server to create an unnamed prepared statement.
2. Send a PARSE message to the server to create an unnamed prepared statement.

#. Send a BIND message to run against the unnamed prepared statement, resulting in an
3. Send a BIND message to run against the unnamed prepared statement, resulting in an
unnamed portal on the server.

#. Send an EXECUTE message to read all the results from the portal.
4. Send an EXECUTE message to read all the results from the portal.

It's also possible to use named prepared statements. In which case the prepared
statement persists on the server, and represented in pg8000 using a
``PreparedStatement`` object. This means that the PARSE step gets executed once up
`PreparedStatement` object. This means that the PARSE step gets executed once up
front, and then only the BIND and EXECUTE steps are repeated subsequently.

There are a lot of PostgreSQL data types, but few primitive data types in Python. By
default, pg8000 doesn't send PostgreSQL data type information in the PARSE step, in
which case PostgreSQL assumes the types implied by the SQL statement. In some cases
PostgreSQL can't work out a parameter type and so an `explicit cast
<https://www.postgresql.org/docs/current/static/sql-expressions.html#SQL-SYNTAX-TYPE-CASTS>`_
PostgreSQL can't work out a parameter type and so an [explicit cast]
(https://www.postgresql.org/docs/current/static/sql-expressions.html#SQL-SYNTAX-TYPE-CASTS)
can be used in the SQL.

In the FEBE protocol, each query parameter can be sent to the server either as binary
or text according to the format code. In pg8000 the parameters are always sent as text.

Occasionally, the network connection between pg8000 and the server may go down. If
pg8000 encounters a network problem it'll raise an ``InterfaceError`` with the message
``network error`` and with the original exception set as the `cause
<https://docs.python.org/3/reference/simple_stmts.html#the-raise-statement>`_.
pg8000 encounters a network problem it'll raise an `InterfaceError` with the message
`network error` and with the original exception set as the [cause]
(https://docs.python.org/3/reference/simple_stmts.html#the-raise-statement).


Native API Docs
---------------
## Native API Docs

`Native API Docs <docs/native_api_docs.rst>`_
[Native API Docs](docs/native_api_docs.rst)


DB-API 2 Docs
-------------
## DB-API 2 Docs

`DB-API 2 Docs <docs/dbapi2_docs.rst>`_
[DB-API 2 Docs](docs/dbapi2_docs.rst)


Design Decisions
----------------
## Design Decisions

For the ``Range`` type, the constructor follows the `PostgreSQL range constructor functions <https://www.postgresql.org/docs/current/rangetypes.html#RANGETYPES-CONSTRUCT>`_
which makes `[closed, open) <https://fhur.me/posts/always-use-closed-open-intervals>`_
For the `Range` type, the constructor follows the [PostgreSQL range constructor functions]
(https://www.postgresql.org/docs/current/rangetypes.html#RANGETYPES-CONSTRUCT)
which makes [[closed, open)](https://fhur.me/posts/always-use-closed-open-intervals)
the easiest to express:

```python
>>> from pg8000.types import Range
>>>
>>> pg_range = Range(2, 6)
```


Tests
-----
## Tests

- Install `tox <http://testrun.org/tox/latest/>`_: ``pip install tox``
- Install [tox](http://testrun.org/tox/latest/): `pip install tox`

- Enable the PostgreSQL hstore extension by running the SQL command:
``create extension hstore;``

- Add a line to ``pg_hba.conf`` for the various authentication options:
`create extension hstore;`

::
- Add a line to `pg_hba.conf` for the various authentication options:

host pg8000_md5 all 127.0.0.1/32 md5
host pg8000_gss all 127.0.0.1/32 gss
host pg8000_password all 127.0.0.1/32 password
host pg8000_scram_sha_256 all 127.0.0.1/32 scram-sha-256
host all all 127.0.0.1/32 trust
```
host pg8000_md5 all 127.0.0.1/32 md5
host pg8000_gss all 127.0.0.1/32 gss
host pg8000_password all 127.0.0.1/32 password
host pg8000_scram_sha_256 all 127.0.0.1/32 scram-sha-256
host all all 127.0.0.1/32 trust
```

- Set password encryption to ``scram-sha-256`` in ``postgresql.conf``:
``password_encryption = 'scram-sha-256'``
- Set password encryption to `scram-sha-256` in `postgresql.conf`:
`password_encryption = 'scram-sha-256'`

- Set the password for the postgres user: ``ALTER USER postgresql WITH PASSWORD 'pw';``
- Set the password for the postgres user: `ALTER USER postgresql WITH PASSWORD 'pw';`

- Run ``tox`` from the ``pg8000`` directory: ``tox``
- Run `tox` from the `pg8000` directory: `tox`

This will run the tests against the Python version of the virtual environment, on the
machine, and the installed PostgreSQL version listening on port 5432, or the ``PGPORT``
machine, and the installed PostgreSQL version listening on port 5432, or the `PGPORT`
environment variable if set.

Benchmarks are run as part of the test suite at ``tests/test_benchmarks.py``.


README.rst
----------
Benchmarks are run as part of the test suite at `tests/test_benchmarks.py`.

This file is written in the `reStructuredText
<https://docutils.sourceforge.io/docs/user/rst/quickref.html>`_ format. To generate an
HTML page from it, do:

- Activate the virtual environment: ``source venv/bin/activate``
- Install ``Sphinx``: ``pip install Sphinx``
- Run ``rst2html.py``: ``rst2html.py README.rst README.html``
## Doing A Release Of pg8000

Run `tox` to make sure all tests pass, then update the release notes, then do:

Doing A Release Of pg8000
-------------------------

Run ``tox`` to make sure all tests pass, then update the release notes, then do:

::

git tag -a x.y.z -m "version x.y.z"
rm -r dist
python -m build
twine upload dist/*
```
git tag -a x.y.z -m "version x.y.z"
rm -r dist
python -m build
twine upload dist/*
``
Release Notes
-------------
## Release Notes
`Release Notes <docs/release_notes.rst>`_
[Release Notes](docs/release_notes.rst)

0 comments on commit 9bba90d

Please sign in to comment.