Skip to content

Commit

Permalink
S01E10
Browse files Browse the repository at this point in the history
  • Loading branch information
ansipunk committed Mar 3, 2024
1 parent cdbf97f commit 6910288
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 7 deletions.
5 changes: 4 additions & 1 deletion databases/backends/aiopg.py
Expand Up @@ -5,13 +5,14 @@
import uuid

import aiopg
from sqlalchemy.dialects.postgresql.psycopg import PGDialect_psycopg
from sqlalchemy.engine.cursor import CursorResultMetaData
from sqlalchemy.engine.interfaces import Dialect, ExecutionContext
from sqlalchemy.sql import ClauseElement
from sqlalchemy.sql.ddl import DDLElement

from databases.backends.common.records import Record, Row, create_column_maps
from databases.backends.compilers.psycopg import PGCompiler_psycopg
from databases.backends.dialects.psycopg import PGDialect_psycopg
from databases.core import LOG_EXTRA, DatabaseURL
from databases.interfaces import (
ConnectionBackend,
Expand All @@ -36,10 +37,12 @@ def _get_dialect(self) -> Dialect:
dialect = PGDialect_psycopg(
json_serializer=json.dumps, json_deserializer=lambda x: x
)
dialect.statement_compiler = PGCompiler_psycopg
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
dialect.supports_native_decimal = True

Expand Down
14 changes: 8 additions & 6 deletions databases/backends/asyncpg.py
Expand Up @@ -2,12 +2,12 @@
import typing

import asyncpg
from sqlalchemy.dialects.postgresql.psycopg import PGDialect_psycopg
from sqlalchemy.engine.interfaces import Dialect
from sqlalchemy.sql import ClauseElement
from sqlalchemy.sql.ddl import DDLElement

from databases.backends.common.records import Record, create_column_maps
from databases.backends.dialects.psycopg import dialect as psycopg_dialect
from databases.core import LOG_EXTRA, DatabaseURL
from databases.interfaces import (
ConnectionBackend,
Expand All @@ -29,14 +29,16 @@ def __init__(
self._pool = None

def _get_dialect(self) -> Dialect:
dialect = PGDialect_psycopg(paramstyle="pyformat")
dialect = psycopg_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
dialect.supports_native_decimal = True

return dialect

def _get_connection_kwargs(self) -> dict:
Expand Down Expand Up @@ -189,10 +191,10 @@ def _compile(self, query: ClauseElement) -> typing.Tuple[str, list, tuple]:
)
return compiled_query, args, result_map

@property
def raw_connection(self) -> asyncpg.connection.Connection:
assert self._connection is not None, "Connection is not acquired"
return self._connection
@property
def raw_connection(self) -> asyncpg.connection.Connection:
assert self._connection is not None, "Connection is not acquired"
return self._connection


class AsyncpgTransaction(TransactionBackend):
Expand Down
Empty file.
17 changes: 17 additions & 0 deletions databases/backends/compilers/psycopg.py
@@ -0,0 +1,17 @@
from sqlalchemy.dialects.postgresql.psycopg import PGCompiler_psycopg


class APGCompiler_psycopg2(PGCompiler_psycopg):
def construct_params(self, *args, **kwargs):
pd = super().construct_params(*args, **kwargs)

for column in self.prefetch:
pd[column.key] = self._exec_default(column.default)

return pd

def _exec_default(self, default):
if default.is_callable:
return default.arg(self.dialect)
else:
return default.arg
Empty file.
42 changes: 42 additions & 0 deletions databases/backends/dialects/psycopg.py
@@ -0,0 +1,42 @@
"""
All the unique changes for the databases package
with the custom Numeric as the deprecated pypostgresql
for backwards compatibility and to make sure the
package can go to SQLAlchemy 2.0+.
"""

import typing

from sqlalchemy.dialects.postgresql.base import PGDialect, PGExecutionContext
from sqlalchemy.engine import processors
from sqlalchemy.types import Numeric


class PGExecutionContext_psycopg(PGExecutionContext):
...


class PGNumeric(Numeric):
def bind_processor(
self, dialect: typing.Any
) -> typing.Union[str, None]: # pragma: no cover
return processors.to_str

def result_processor(
self, dialect: typing.Any, coltype: typing.Any
) -> typing.Union[float, None]: # pragma: no cover
if self.asdecimal:
return None
else:
return processors.to_float


class PGDialect_psycopg(PGDialect):
colspecs = {
**PGDialect.colspecs,
Numeric: PGNumeric,
}
execution_ctx_cls = PGExecutionContext_psycopg


dialect = PGDialect_psycopg

0 comments on commit 6910288

Please sign in to comment.