Skip to content

Commit

Permalink
Added get_dialect function (#84)
Browse files Browse the repository at this point in the history
* Added `get_dialect` function

* Added test; Updated documentation
  • Loading branch information
Gr1N authored and nhumrich committed May 16, 2018
1 parent b867968 commit 3fba01b
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 14 deletions.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ nosetests.xml
coverage.xml
*,cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
Expand All @@ -66,6 +67,9 @@ docs/_build/
# PyBuilder
target/

# mypy
.mypy_cache/

# IPython Notebook
.ipynb_checkpoints

Expand All @@ -87,3 +91,8 @@ ENV/

# Rope project settings
.ropeproject

# VisualStudioCode #
.vscode/*
.history
*.code-workspace
22 changes: 15 additions & 7 deletions asyncpgsa/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,21 @@

from .log import query_logger

_dialect = pypostgresql.dialect(paramstyle='pyformat')
_dialect.implicit_returning = True
_dialect.supports_native_enum = True
_dialect.supports_smallserial = True # 9.2+
_dialect._backslash_escapes = False
_dialect.supports_sane_multi_rowcount = True # psycopg 2.0.9+
_dialect._has_native_hstore = True

def get_dialect(**kwargs):
dialect = pypostgresql.dialect(paramstyle='pyformat', **kwargs)

dialect.implicit_returning = True
dialect.supports_native_enum = True
dialect.supports_smallserial = True # 9.2+
dialect._backslash_escapes = False
dialect.supports_sane_multi_rowcount = True # psycopg 2.0.9+
dialect._has_native_hstore = True

return dialect


_dialect = get_dialect()


def execute_defaults(query):
Expand Down
47 changes: 41 additions & 6 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to asyncpgsa's
Welcome to asyncpgsa's
=====================================

A python library wrapper around asyncpg for use with sqlalchemy.
Expand Down Expand Up @@ -69,8 +69,8 @@ PG Singleton
^^^^^^^^^^^^
If you want the highest level of abstraction, you can can use the singleton object. This will create a pool for you.

Init
++++
Init
++++
Before you can run any queries you first have to initialize the pool

.. code-block:: python
Expand All @@ -87,7 +87,7 @@ Before you can run any queries you first have to initialize the pool
)
Query
+++++
+++++
Query is for making read only select statements.
This method will create a prepared statement for you and return a cursor object that will get a couple rows at a time from the database.
This is great for select statements with lots of results.
Expand Down Expand Up @@ -190,7 +190,7 @@ Creating the pool
max_size=10
)
Transaction
Transaction
+++++++++++
The transaction context manager will establish a connection and start a transaction all at once. It returns the connection object. Commits and rollbacks will be handled for you.

Expand Down Expand Up @@ -264,6 +264,42 @@ json
...
As another option you can initialize PostgreSQL dialect with custom JSON serializer and deserializer and pass it into `pg.init`

.. code-block:: python
from asyncpgsa.connection import get_dialect
async def main():
dialect = get_dialect(
json_serializer=json.dumps,
json_deserializer=ujson.loads
)
await pg.init("postgresql://127.0.0.1/template0", dialect=dialect)
...
Also you can initialize pool with custom dialect

.. code-block:: python
import asyncpgsa
from asyncpgsa.connection import get_dialect
async def main():
dialect = get_dialect(
json_serializer=json.dumps,
json_deserializer=ujson.loads
)
await asyncpgsa.create_pool(
dialect=dialect,
...
)
...
Compile
=======
Expand Down Expand Up @@ -328,4 +364,3 @@ And another where there are multiple queries
.. toctree::
:maxdepth: 2
32 changes: 31 additions & 1 deletion tests/test_connection.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import enum
import json
import logging
import uuid
from functools import partial

from asyncpgsa import connection
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

from asyncpgsa import connection

file_table = sa.Table(
'meows', sa.MetaData(),
Expand Down Expand Up @@ -95,3 +99,29 @@ def test_compile_query_no_debug(caplog):
results, _ = connection.compile_query(query)
msgs = [record.msg for record in caplog.records]
assert results not in msgs


def test_compile_jsonb_with_custom_json_encoder():
jsonb_table = sa.Table(
'meowsb', sa.MetaData(),
sa.Column('data', postgresql.JSONB),
)

class JSONEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, uuid.UUID):
return str(o)
else:
return super().default(o)

dialect = connection.get_dialect(
json_serializer=partial(json.dumps, cls=JSONEncoder)
)

data = {
'uuid4': uuid.uuid4(),
}
query = jsonb_table.insert().values(data=data)
q, p = connection.compile_query(query, dialect=dialect)
assert q == 'INSERT INTO meowsb (data) VALUES ($1)'
assert p == ['{"uuid4": "%s"}' % data['uuid4']]

0 comments on commit 3fba01b

Please sign in to comment.