From: Mike Bayer Date: Tue, 10 Dec 2013 02:27:14 +0000 (-0500) Subject: - round trip test X-Git-Tag: rel_0_9_0~41^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=164bff07496c345c3c57a8b26439aa6a0fbce3b8;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - round trip test - changelog - some doc rearrangement --- diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index 4656fcf331..e658e6928f 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -14,6 +14,14 @@ .. changelog:: :version: 0.9.0b2 + .. change:: + :tags: feature, postgresql + :pullreq: bitbucket:8 + + Added support for Postgresql TSVECTOR via the + :class:`.postgresql.TSVECTOR` type. Pull request courtesy + Noufal Ibrahim. + .. change:: :tags: feature, engine :tickets: 2875 diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py index 7602304f83..d3380afdd7 100644 --- a/lib/sqlalchemy/dialects/postgresql/base.py +++ b/lib/sqlalchemy/dialects/postgresql/base.py @@ -131,6 +131,44 @@ use the :meth:`._UpdateBase.returning` method on a per-statement basis:: where(table.c.name=='foo') print result.fetchall() +.. _postgresql_match: + +Full Text Search +---------------- + +SQLAlchemy makes available the Postgresql ``@@`` operator via the +:meth:`.ColumnElement.match` method on any textual column expression. +On a Postgresql dialect, an expression like the following:: + + select([sometable.c.text.match("search string")]) + +will emit to the database:: + + SELECT text @@ to_tsquery('search string') FROM table + +The Postgresql text search functions such as ``to_tsquery()`` +and ``to_tsvector()`` are available +explicitly using the standard :attr:`.func` construct. For example:: + + select([ + func.to_tsvector('fat cats ate rats').match('cat & rat') + ]) + +Emits the equivalent of:: + + SELECT to_tsvector('fat cats ate rats') @@ to_tsquery('cat & rat') + +The :class:`.postgresql.TSVECTOR` type can provide for explicit CAST:: + + from sqlalchemy.dialects.postgresql import TSVECTOR + from sqlalchemy import select, cast + select([cast("some text", TSVECTOR)]) + +produces a statement equivalent to:: + + SELECT CAST('some text' AS TSVECTOR) AS anon_1 + + FROM ONLY ... ------------------------ @@ -369,29 +407,17 @@ class UUID(sqltypes.TypeEngine): PGUuid = UUID class TSVECTOR(sqltypes.TypeEngine): - """The TSVECTOR type implements the Postgresql text search type - TSVECTOR. + """The :class:`.postgresql.TSVECTOR` type implements the Postgresql + text search type TSVECTOR. It can be used to do full text queries on natural language - *documents*. + documents. - Search queries are performed using the ``@@`` operator in - postgresql. This is made available with the ``match`` method - available on the column. + .. versionadded:: 0.9.0 - This means that if you have a table ``Example`` with a column - ``text`` of type ``TSVECTOR``, you can create a search clause like - so - - :: - - Example.text.match("search string") - - which will be compiled to - - :: + .. seealso:: - text @@ to_tsquery('search string') + :ref:`postgresql_match` """ __visit_name__ = 'TSVECTOR' diff --git a/test/dialect/postgresql/test_types.py b/test/dialect/postgresql/test_types.py index dc7b246641..6e8609448b 100644 --- a/test/dialect/postgresql/test_types.py +++ b/test/dialect/postgresql/test_types.py @@ -869,6 +869,17 @@ class SpecialTypesTest(fixtures.TestBase, ComparesTables, AssertsCompiledSQL): for type_, expected in pairs: self.assert_compile(type_, expected) + @testing.provide_metadata + def test_tsvector_round_trip(self): + t = Table('t1', self.metadata, Column('data', postgresql.TSVECTOR)) + t.create() + testing.db.execute(t.insert(), data="a fat cat sat") + eq_(testing.db.scalar(select([t.c.data])), "'a' 'cat' 'fat' 'sat'") + + testing.db.execute(t.update(), data="'a' 'cat' 'fat' 'mat' 'sat'") + + eq_(testing.db.scalar(select([t.c.data])), "'a' 'cat' 'fat' 'mat' 'sat'") + @testing.provide_metadata def test_bit_reflection(self): metadata = self.metadata