Add Asterisk compiler

This commit is contained in:
Konsta Vesterinen
2015-06-05 09:48:27 +03:00
parent 0cd297c4fc
commit e6c360aeff
6 changed files with 57 additions and 10 deletions

View File

@@ -4,23 +4,25 @@ Changelog
Here you can see the full list of changes between each SQLAlchemy-Utils release. Here you can see the full list of changes between each SQLAlchemy-Utils release.
0.30.8 (2015-06-xx) 0.30.8 (2015-06-05)
^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
- Make has_index work with tables without primary keys (#148) - Added Asterisk compiler
- Made quote function accept dialect object as the first paremeter
- Made has_index work with tables without primary keys (#148)
0.30.7 (2015-05-28) 0.30.7 (2015-05-28)
^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
- Fix CompositeType null handling - Fixed CompositeType null handling
0.30.6 (2015-05-28) 0.30.6 (2015-05-28)
^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
- Make psycopg2 requirement optional (#145, #146) - Made psycopg2 requirement optional (#145, #146)
- Make CompositeArray work with tuples given as bind parameters - Made CompositeArray work with tuples given as bind parameters
0.30.5 (2015-05-27) 0.30.5 (2015-05-27)

View File

@@ -8,6 +8,7 @@ from .asserts import ( # noqa
) )
from .exceptions import ImproperlyConfigured # noqa from .exceptions import ImproperlyConfigured # noqa
from .expression_parser import ExpressionParser # noqa from .expression_parser import ExpressionParser # noqa
from .expressions import Asterisk # noqa
from .functions import ( # noqa from .functions import ( # noqa
analyze, analyze,
create_database, create_database,

View File

@@ -1,12 +1,16 @@
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy.ext.compiler import compiles from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql import expression from sqlalchemy.sql.elements import ColumnClause
from sqlalchemy.sql.expression import ( from sqlalchemy.sql.expression import (
_literal_as_text, _literal_as_text,
ClauseElement, ClauseElement,
Executable ColumnElement,
Executable,
FunctionElement
) )
from sqlalchemy_utils.functions.orm import quote
class explain(Executable, ClauseElement): class explain(Executable, ClauseElement):
""" """
@@ -64,7 +68,7 @@ def pg_explain(element, compiler, **kw):
return text return text
class array_get(expression.FunctionElement): class array_get(FunctionElement):
name = 'array_get' name = 'array_get'
@@ -85,3 +89,13 @@ def compile_array_get(element, compiler, **kw):
compiler.process(args[0]), compiler.process(args[0]),
sa.text(str(args[1].value + 1)) sa.text(str(args[1].value + 1))
) )
class Asterisk(ColumnElement):
def __init__(self, selectable):
self.selectable = selectable
@compiles(Asterisk)
def compile_asterisk(element, compiler, **kw):
return '%s.*' % quote(compiler.dialect, element.selectable.name)

View File

@@ -13,6 +13,7 @@ from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import mapperlib from sqlalchemy.orm import mapperlib
from sqlalchemy.orm.attributes import InstrumentedAttribute from sqlalchemy.orm.attributes import InstrumentedAttribute
from sqlalchemy.orm.exc import UnmappedInstanceError from sqlalchemy.orm.exc import UnmappedInstanceError
from sqlalchemy.engine.interfaces import Dialect
from sqlalchemy.orm.properties import ColumnProperty from sqlalchemy.orm.properties import ColumnProperty
from sqlalchemy.orm.query import _ColumnEntity from sqlalchemy.orm.query import _ColumnEntity
from sqlalchemy.orm.session import object_session from sqlalchemy.orm.session import object_session
@@ -407,10 +408,13 @@ def quote(mixed, ident):
# 'some_other_identifier' # 'some_other_identifier'
:param mixed: SQLAlchemy Session / Connection / Engine object. :param mixed: SQLAlchemy Session / Connection / Engine / Dialect object.
:param ident: identifier to conditionally quote :param ident: identifier to conditionally quote
""" """
dialect = get_bind(mixed).dialect if isinstance(mixed, Dialect):
dialect = mixed
else:
dialect = get_bind(mixed).dialect
return dialect.preparer(dialect).quote(ident) return dialect.preparer(dialect).quote(ident)

View File

@@ -1,3 +1,4 @@
from sqlalchemy.dialects import postgresql
from sqlalchemy_utils.functions import quote from sqlalchemy_utils.functions import quote
from tests import TestCase from tests import TestCase
@@ -7,8 +8,10 @@ class TestQuote(TestCase):
assert quote(self.connection, 'order') == '"order"' assert quote(self.connection, 'order') == '"order"'
assert quote(self.session, 'order') == '"order"' assert quote(self.session, 'order') == '"order"'
assert quote(self.engine, 'order') == '"order"' assert quote(self.engine, 'order') == '"order"'
assert quote(postgresql.dialect(), 'order') == '"order"'
def test_quote_with_non_preserved_keyword(self): def test_quote_with_non_preserved_keyword(self):
assert quote(self.connection, 'some_order') == 'some_order' assert quote(self.connection, 'some_order') == 'some_order'
assert quote(self.session, 'some_order') == 'some_order' assert quote(self.session, 'some_order') == 'some_order'
assert quote(self.engine, 'some_order') == 'some_order' assert quote(self.engine, 'some_order') == 'some_order'
assert quote(postgresql.dialect(), 'some_order') == 'some_order'

View File

@@ -1,6 +1,7 @@
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy.dialects import postgresql from sqlalchemy.dialects import postgresql
from sqlalchemy_utils import Asterisk
from sqlalchemy_utils.expressions import explain, explain_analyze from sqlalchemy_utils.expressions import explain, explain_analyze
from tests import TestCase from tests import TestCase
@@ -83,3 +84,25 @@ class TestExplainAnalyze(ExpressionTestCase):
dialect=postgresql.dialect() dialect=postgresql.dialect()
) )
).startswith('EXPLAIN (ANALYZE true) SELECT') ).startswith('EXPLAIN (ANALYZE true) SELECT')
class TestAsterisk(object):
def test_with_table_object(self):
Base = sa.ext.declarative.declarative_base()
class Article(Base):
__tablename__ = 'article'
id = sa.Column(sa.Integer, primary_key=True)
assert str(Asterisk(Article.__table__)) == 'article.*'
def test_with_table_object(self):
Base = sa.ext.declarative.declarative_base()
class User(Base):
__tablename__ = 'user'
id = sa.Column(sa.Integer, primary_key=True)
assert str(Asterisk(User.__table__).compile(
dialect=postgresql.dialect()
)) == '"user".*'