>>> from sqlalchemy import func
- >>> print func.row_number().over(order_by='x', range_=(-5, 10))
+ >>> print(func.row_number().over(order_by='x', range_=(-5, 10)))
row_number() OVER (ORDER BY x RANGE BETWEEN :param_1 PRECEDING AND :param_2 FOLLOWING)
- >>> print func.row_number().over(order_by='x', rows=(None, 0))
+ >>> print(func.row_number().over(order_by='x', rows=(None, 0)))
row_number() OVER (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- >>> print func.row_number().over(order_by='x', range_=(-2, None))
+ >>> print(func.row_number().over(order_by='x', range_=(-2, None)))
row_number() OVER (ORDER BY x RANGE BETWEEN :param_1 PRECEDING AND UNBOUNDED FOLLOWING)
:paramref:`.expression.over.range_` and :paramref:`.expression.over.rows` are specified as
:meth:`.ColumnOperators.isnot_distinct_from` allow the IS DISTINCT
FROM and IS NOT DISTINCT FROM sql operation::
- >>> print column('x').is_distinct_from(None)
+ >>> print(column('x').is_distinct_from(None))
x IS DISTINCT FROM NULL
Handling is provided for NULL, True and False::
- >>> print column('x').isnot_distinct_from(False)
+ >>> print(column('x').isnot_distinct_from(False))
x IS NOT DISTINCT FROM false
For SQLite, which doesn't have this operator, "IS" / "IS NOT" is rendered,
which on SQLite works for NULL unlike other backends::
>>> from sqlalchemy.dialects import sqlite
- >>> print column('x').is_distinct_from(None).compile(dialect=sqlite.dialect())
+ >>> print(column('x').is_distinct_from(None).compile(dialect=sqlite.dialect()))
x IS NOT NULL
.. _change_1957:
>>> from sqlalchemy.schema import MetaData, Table, Column, CreateTable
>>> from sqlalchemy.types import String
>>> t = Table('t', MetaData(), Column('x', String(), server_default="hi ' there"))
- >>> print CreateTable(t)
+ >>> print(CreateTable(t))
CREATE TABLE t (
x VARCHAR DEFAULT 'hi '' there'
>>> my_seq = Sequence('some_sequence')
>>> stmt = select([my_seq.next_value()])
- >>> print stmt.compile(dialect=postgresql.dialect())
+ >>> print(stmt.compile(dialect=postgresql.dialect()))
SELECT nextval('some_sequence') AS next_value_1
.. _sequence_metadata:
e.g. the highest? Then this expression makes more parenthesis, but is
otherwise OK, that is, these two are equivalent::
- >>> print (column('q') - column('y')).op('+', precedence=100)(column('z'))
+ >>> print((column('q') - column('y')).op('+', precedence=100)(column('z')))
(q - y) + z
- >>> print (column('q') - column('y')).op('+')(column('z'))
+ >>> print((column('q') - column('y')).op('+')(column('z')))
q - y + z
but these two are not::
- >>> print column('q') - column('y').op('+', precedence=100)(column('z'))
+ >>> print(column('q') - column('y').op('+', precedence=100)(column('z')))
q - y + z
- >>> print column('q') - column('y').op('+')(column('z'))
+ >>> print(column('q') - column('y').op('+')(column('z')))
q - (y + z)
For now, it's not clear that as long as we are doing parenthesization based on
q = q.options(RelationshipCache(Person.addresses, "default"))
# query
- print q.all()
+ print(q.all())
To run, both SQLAlchemy and dogpile.cache must be
installed or on the current PYTHONPATH. The demo will create a local
# locate documents with a certain path/attribute structure
for document in find_document('/somefile/header/field2[@attr=foo]'):
# dump the XML
- print document
+ print(document)
.. autosource::
:files: pickle_type.py, adjacency_list.py, optimized_al.py
n2 = Node(2)
n5 = Node(5)
n2.add_neighbor(n5)
- print n2.higher_neighbors()
+ print(n2.higher_neighbors())
.. autosource::
E.g.::
- print session.query(Road).filter(
- Road.road_geom.intersects(r1.road_geom)).all()
+ print(session.query(Road).filter(
+ Road.road_geom.intersects(r1.road_geom)).all())
.. autosource::
filter(Animal.facts.any(
and_(AnimalFact.key == u'weasel-like',
AnimalFact.value == True))))
- print 'weasel-like animals', q.all()
+ print('weasel-like animals', q.all())
.. autosource::
# INSERT..RETURNING
result = table.insert().returning(table.c.col1, table.c.col2).\
values(name='foo')
- print result.fetchall()
+ print(result.fetchall())
# UPDATE..RETURNING
raises = empl.update().returning(empl.c.id, empl.c.salary).\
where(empl.c.sales>100).\
values(dict(salary=empl.c.salary * 1.1))
- print raises.fetchall()
+ print(raises.fetchall())
.. _dialects: http://mc-computing.com/Databases/Firebird/SQL_Dialect.html
conn = engine.connect().execution_options(enable_rowcount=True)
r = conn.execute(stmt)
- print r.rowcount
+ print(r.rowcount)
* ``retaining`` - False by default. Setting this to True will pass the
``retaining=True`` keyword argument to the ``.commit()`` and ``.rollback()``
# INSERT..RETURNING
result = table.insert().returning(table.c.col1, table.c.col2).\
values(name='foo')
- print result.fetchall()
+ print(result.fetchall())
# UPDATE..RETURNING
result = table.update().returning(table.c.col1, table.c.col2).\
where(table.c.name=='foo').values(name='bar')
- print result.fetchall()
+ print(result.fetchall())
# DELETE..RETURNING
result = table.delete().returning(table.c.col1, table.c.col2).\
where(table.c.name=='foo')
- print result.fetchall()
+ print(result.fetchall())
.. _postgresql_insert_on_conflict:
# SELECT ... FROM ONLY ...
result = table.select().with_hint(table, 'ONLY', 'postgresql')
- print result.fetchall()
+ print(result.fetchall())
# UPDATE ONLY ...
table.update(values=dict(foo='bar')).with_hint('ONLY',
from sqlalchemy import select
s = select([MyColumn('x'), MyColumn('y')])
- print str(s)
+ print(str(s))
Produces::
)
insert = InsertFromSelect(t1, select([t1]).where(t1.c.x>5))
- print insert
+ print(insert)
Produces::
the argument, which when evaluated with SQLAlchemy expression mechanics
returns a new SQL expression::
- >>> print Interval.length
+ >>> print(Interval.length)
interval."end" - interval.start
- >>> print Session().query(Interval).filter(Interval.length > 10)
+ >>> print(Session().query(Interval).filter(Interval.length > 10))
SELECT interval.id AS interval_id, interval.start AS interval_start,
interval."end" AS interval_end
FROM interval
ORM methods such as :meth:`~.Query.filter_by` generally use ``getattr()`` to
locate attributes, so can also be used with hybrid attributes::
- >>> print Session().query(Interval).filter_by(length=5)
+ >>> print(Session().query(Interval).filter_by(length=5))
SELECT interval.id AS interval_id, interval.start AS interval_start,
interval."end" AS interval_end
FROM interval
>>> i1.intersects(Interval(25, 29))
False
- >>> print Session().query(Interval).filter(Interval.contains(15))
+ >>> print(Session().query(Interval).filter(Interval.contains(15)))
SELECT interval.id AS interval_id, interval.start AS interval_start,
interval."end" AS interval_end
FROM interval
WHERE interval.start <= :start_1 AND interval."end" > :end_1
>>> ia = aliased(Interval)
- >>> print Session().query(Interval, ia).filter(Interval.intersects(ia))
+ >>> print(Session().query(Interval, ia).filter(Interval.intersects(ia)))
SELECT interval.id AS interval_id, interval.start AS interval_start,
interval."end" AS interval_end, interval_1.id AS interval_1_id,
interval_1.start AS interval_1_start, interval_1."end" AS interval_1_end
>>> i1.radius
2
- >>> print Session().query(Interval).filter(Interval.radius > 5)
+ >>> print(Session().query(Interval).filter(Interval.radius > 5))
SELECT interval.id AS interval_id, interval.start AS interval_start,
interval."end" AS interval_end
FROM interval
be used in an appropriate context such that an appropriate join to
``SavingsAccount`` will be present::
- >>> print Session().query(User, User.balance).\
- ... join(User.accounts).filter(User.balance > 5000)
+ >>> print(Session().query(User, User.balance).
+ ... join(User.accounts).filter(User.balance > 5000))
SELECT "user".id AS user_id, "user".name AS user_name,
account.balance AS account_balance
FROM "user" JOIN account ON "user".id = account.user_id
The above recipe will give us the ``balance`` column which renders
a correlated SELECT::
- >>> print s.query(User).filter(User.balance > 400)
+ >>> print(s.query(User).filter(User.balance > 400))
SELECT "user".id AS user_id, "user".name AS user_name
FROM "user"
WHERE (SELECT sum(account.balance) AS sum_1
Above, SQL expressions against ``word_insensitive`` will apply the ``LOWER()``
SQL function to both sides::
- >>> print Session().query(SearchWord).filter_by(word_insensitive="Trucks")
+ >>> print(Session().query(SearchWord).filter_by(word_insensitive="Trucks"))
SELECT searchword.id AS searchword_id, searchword.word AS searchword_word
FROM searchword
WHERE lower(searchword.word) = lower(:lower_1)
universally, including SQL expression vs. Python expression (note the Python
value is converted to lower case on the Python side here)::
- >>> print Session().query(SearchWord).filter_by(word_insensitive="Trucks")
+ >>> print(Session().query(SearchWord).filter_by(word_insensitive="Trucks"))
SELECT searchword.id AS searchword_id, searchword.word AS searchword_word
FROM searchword
WHERE lower(searchword.word) = :lower_1
>>> sw1 = aliased(SearchWord)
>>> sw2 = aliased(SearchWord)
- >>> print Session().query(
+ >>> print(Session().query(
... sw1.word_insensitive,
... sw2.word_insensitive).\
... filter(
... sw1.word_insensitive > sw2.word_insensitive
- ... )
+ ... ))
SELECT lower(searchword_1.word) AS lower_1,
lower(searchword_2.word) AS lower_2
FROM searchword AS searchword_1, searchword AS searchword_2
True
>>> ws1.word_insensitive == "XOmEwOrX"
False
- >>> print ws1.word_insensitive
+ >>> print(ws1.word_insensitive)
someword
The Hybrid Value pattern is very useful for any kind of value that may have
A mapping like the above allows the ``word_insensitive`` attribute
to render an expression like::
- >>> print SearchWord.word_insensitive == "Trucks"
+ >>> print(SearchWord.word_insensitive == "Trucks")
lower(search_word.word) = lower(:lower_1)
:param comparator_factory:
from sqlalchemy import event
def my_load_listener(target, context):
- print "on load!"
+ print("on load!")
event.listen(SomeClass, 'load', my_load_listener)
from sqlalchemy.orm import sessionmaker
def my_before_commit(session):
- print "before commit!"
+ print("before commit!")
Session = sessionmaker()
elements replaced with values taken from the given dictionary::
>>> clause = column('x') + bindparam('foo')
- >>> print clause.compile().params
+ >>> print(clause.compile().params)
{'foo':None}
- >>> print clause.params({'foo':7}).compile().params
+ >>> print(clause.params({'foo':7}).compile().params)
{'foo':7}
"""
s = select([t]).where(t.c.x == 5)
- print s.compile(compile_kwargs={"literal_binds": True})
+ print(s.compile(compile_kwargs={"literal_binds": True}))
.. versionadded:: 0.9.0
>>> from sqlalchemy.sql import column
>>> column('a') + column('b')
<sqlalchemy.sql.expression.BinaryExpression object at 0x101029dd0>
- >>> print column('a') + column('b')
+ >>> print(column('a') + column('b'))
a + b
.. seealso::
E.g.::
>>> from sqlalchemy import false
- >>> print select([t.c.x]).where(false())
+ >>> print(select([t.c.x]).where(false()))
SELECT x FROM t WHERE false
A backend which does not support true/false constants will render as
an expression against 1 or 0::
- >>> print select([t.c.x]).where(false())
+ >>> print(select([t.c.x]).where(false()))
SELECT x FROM t WHERE 0 = 1
The :func:`.true` and :func:`.false` constants also feature
"short circuit" operation within an :func:`.and_` or :func:`.or_`
conjunction::
- >>> print select([t.c.x]).where(or_(t.c.x > 5, true()))
+ >>> print(select([t.c.x]).where(or_(t.c.x > 5, true())))
SELECT x FROM t WHERE true
- >>> print select([t.c.x]).where(and_(t.c.x > 5, false()))
+ >>> print(select([t.c.x]).where(and_(t.c.x > 5, false())))
SELECT x FROM t WHERE false
.. versionchanged:: 0.9 :func:`.true` and :func:`.false` feature
E.g.::
>>> from sqlalchemy import true
- >>> print select([t.c.x]).where(true())
+ >>> print(select([t.c.x]).where(true()))
SELECT x FROM t WHERE true
A backend which does not support true/false constants will render as
an expression against 1 or 0::
- >>> print select([t.c.x]).where(true())
+ >>> print(select([t.c.x]).where(true()))
SELECT x FROM t WHERE 1 = 1
The :func:`.true` and :func:`.false` constants also feature
"short circuit" operation within an :func:`.and_` or :func:`.or_`
conjunction::
- >>> print select([t.c.x]).where(or_(t.c.x > 5, true()))
+ >>> print(select([t.c.x]).where(or_(t.c.x > 5, true())))
SELECT x FROM t WHERE true
- >>> print select([t.c.x]).where(and_(t.c.x > 5, false()))
+ >>> print(select([t.c.x]).where(and_(t.c.x > 5, false())))
SELECT x FROM t WHERE false
.. versionchanged:: 0.9 :func:`.true` and :func:`.false` feature
>>> from sqlalchemy.sql import column
>>> column('a') + column('b')
<sqlalchemy.sql.expression.BinaryExpression object at 0x101029dd0>
- >>> print column('a') + column('b')
+ >>> print(column('a') + column('b'))
a + b
"""
class as_utc(GenericFunction):
type = DateTime
- print select([func.as_utc()])
+ print(select([func.as_utc()]))
User-defined generic functions can be organized into
packages by specifying the "package" attribute when defining
The above function would be available from :data:`.func`
using the package name ``time``::
- print select([func.time.as_utc()])
+ print(select([func.time.as_utc()]))
A final option is to allow the function to be accessed
from one name in :data:`.func` but to render as a different name.
>>> table1 = table('t1', column('a'), column('b'))
>>> table2 = table('t2', column('a'), column('b'))
>>> s1 = select([table1.c.a, table2.c.b])
- >>> print s1
+ >>> print(s1)
SELECT t1.a, t2.b FROM t1, t2
>>> s2 = s1.with_only_columns([table2.c.b])
- >>> print s2
+ >>> print(s2)
SELECT t2.b FROM t1
The preferred way to maintain a specific FROM clause
... select_from(table1.join(table2,
... table1.c.a==table2.c.a))
>>> s2 = s1.with_only_columns([table2.c.b])
- >>> print s2
+ >>> print(s2)
SELECT t2.b FROM t1 JOIN t2 ON t1.a=t2.a
Care should also be taken to use the correct
E.g.::
>>> from sqlalchemy import cast, select, String
- >>> print select([cast('some string', String(collation='utf8'))])
+ >>> print(select([cast('some string', String(collation='utf8'))]))
SELECT CAST(:param_1 AS VARCHAR COLLATE utf8) AS anon_1
:param convert_unicode: When set to ``True``, the