Operator Reference

この項では、SQL式の作成に使用できる演算子の使用方法について詳しく説明します。

これらのメソッドは、 Operators および ColumnOperators 基本クラスで表現されます。これらのメソッドは、次のようなクラスの子孫で使用できます。

  • ColumnElement オブジェクト。より一般的には、すべてのコアSQL式言語の列レベルの式のルートです。

演算子については、最初に次のチュートリアルのセクションで説明します。

Comparison Operators

数値、文字列、日付など、多くのデータ型に適用される基本的な比較:

IN Comparisons

SQLAlchemyでは、SQL IN演算子はそれ自体が主体です。IN演算子は通常、固定値のリストに対して使用されるため、SQLAlchemyのバウンドパラメータ強制機能では、特殊な形式のSQLコンパイルを使用して、コンパイル用の中間SQL文字列をレンダリングします。この文字列は、2番目のステップでバウンドパラメータの最終リストに形成されます。言い換えれば、 “うまくいく” ということです。

IN against a list of values

INは通常、値のリストを ColumnOperators.in_() メソッドに渡すことで使用できます:

>>> print(column("x").in_([1, 2, 3]))
x IN (__[POSTCOMPILE_x_1])

以下に示すように、特殊なバウンド形式の __[POSTCOMPILE は、実行時に個々のパラメータにレンダリングされます。

>>> stmt = select(User.id).where(User.id.in_([1, 2, 3]))
>>> result = conn.execute(stmt)
{execsql}SELECT user_account.id
FROM user_account
WHERE user_account.id IN (?, ?, ?)
[...] (1, 2, 3){stop}

Empty IN Expressions

空のIN式

SQLAlchemyは、行を返さないバックエンド固有の副問い合わせを描画することで、空のIN式に対して数学的に有効な結果を生成します。言い換えれば、”ちゃんと動く”ということです:

>>> stmt = select(User.id).where(User.id.in_([]))
>>> result = conn.execute(stmt)
SELECT user_account.id FROM user_account WHERE user_account.id IN (SELECT 1 FROM (SELECT 1) WHERE 1!=1) [...] ()

上記の”空のセット”サブクエリは正しく一般化され、そのままのIN演算子でレンダリングされます。

NOT IN

“NOT IN”は ColumnOperators.not_in() 演算子で使用できます:

>>> print(column("x").not_in([1, 2, 3]))
(x NOT IN (__[POSTCOMPILE_x_1]))

これは通常、 ~ 演算子を使って否定することで簡単に実現できます:

>>> print(~column("x").in_([1, 2, 3]))
(x NOT IN (__[POSTCOMPILE_x_1]))

Tuple IN Expressions

タプルのIN式

タプル同士の比較はINでは一般的であり、他の使用例の中でも、行を潜在的な複合主キー値の集合に一致させる場合に適応します。 tuple_() 構文は、タプル比較の基本的な構成要素を提供します。 Tuple.in_() 演算子はタプルのリストを受け取ります:

>>> from sqlalchemy import tuple_
>>> tup = tuple_(column("x", Integer), column("y", Integer))
>>> expr = tup.in_([(1, 2), (3, 4)])
>>> print(expr)
(x, y) IN (__[POSTCOMPILE_param_1])

レンダリングされたパラメータを説明します。

>>> tup = tuple_(User.id, Address.id)
>>> stmt = select(User.name).join(Address).where(tup.in_([(1, 1), (2, 2)]))
>>> conn.execute(stmt).all()
{execsql}SELECT user_account.name
FROM user_account JOIN address ON user_account.id = address.user_id
WHERE (user_account.id, address.id) IN (VALUES (?, ?), (?, ?))
[...] (1, 1, 2, 2){stop}
[('spongebob',), ('sandy',)]

Subquery IN

最後に、 ColumnOperators.in_() 演算子と ColumnOperators.not_in() 演算子はサブクエリで動作します。この形式では、 Select 構文が、名前付きサブクエリに明示的に変換されることなく、直接渡されます:

>>> print(column("x").in_(select(user_table.c.id)))
x IN (SELECT user_account.id FROM user_account)

タプルは期待通りに動作します:

>>> print(
...     tuple_(column("x"), column("y")).in_(
...         select(user_table.c.id, address_table.c.id).join(address_table)
...     )
... )
(x, y) IN (SELECT user_account.id, address.id FROM user_account JOIN address ON user_account.id = address.user_id)

Identity Comparisons

These operators involve testing for special SQL values such as``NULL``, boolean constants such as true or false which somedatabases support:

これらの演算子は、 NULL のような特殊なSQL値や、一部のデータベースでサポートされている truefalse のようなブール定数のテストを行います。

  • ColumnOperators.is_() :

    この演算子は”x IS y”のSQLを正確に提供します。”<expr> IS NULL”のように見えます。 NULL 定数は通常のPythonの None を使って簡単に取得できます:

    >>> print(column("x").is_(None))
    
    x IS NULL

    必要であれば、 null() 構文を使って、SQL NULLを明示的に使用することもできます:

    >>> from sqlalchemy import null
    >>> print(column("x").is_(null()))
    
    x IS NULL

    ColumnOperators.is_() 演算子は、 ColumnOperators.__eq__() オーバーロードされた演算子、つまり ==None または null() 値と一緒に使用すると、自動的に呼び出されます。このように、特に動的な値と一緒に使用する場合、通常は ColumnOperators.is_() を明示的に使用する必要はありません:

    >>> a = None
    >>> print(column("x") == a)
    
    x IS NULL

    Pythonの is 演算子は**オーバーロードされていない**ことに注意してください。Pythonは ==!= などのオーバーロード演算子のフックを提供していますが、 is を再定義する方法は 提供していません

  • ColumnOperators.is_not():

    ColumnOperators.is_() と同様に、”IS NOT”を生成します:

    >>> print(column("x").is_not(None))
    
    x IS NOT NULL

    Is similarly equivalent to != None:

    >>> print(column("x") != None)
    
    x IS NOT NULL
  • ColumnOperators.is_distinct_from() :

    Produces SQLはとは異なります。:

    >>> print(column("x").is_distinct_from("some value"))
    
    x IS DISTINCT FROM :x_1
  • ColumnOperators.isnot_distinct_from() :

    IS NOT DISTINCT FROMを生成します。:

    >>> print(column("x").isnot_distinct_from("some value"))
    
    x IS NOT DISTINCT FROM :x_1

String Comparisons

  • ColumnOperators.like()

    >>> print(column("x").like("word"))
    
    x LIKE :x_1
  • ColumnOperators.ilike() :

    大文字小文字を区別しないLIKEは、一般的なバックエンドではSQLの lower() 関数を使用しますが、PostgreSQLのバックエンドでは ILIKE を使用します:

    >>> print(column("x").ilike("word"))
    
    lower(x) LIKE lower(:x_1)
  • ColumnOperators.notlike():

    >>> print(column("x").notlike("word"))
    
    x NOT LIKE :x_1
  • ColumnOperators.notilike():

    >>> print(column("x").notilike("word"))
    
    lower(x) NOT LIKE lower(:x_1)

String Containment

文字列包含演算子は基本的にLIKEと文字列連結演算子の組み合わせで構築されます。文字列連結演算子はほとんどのバックエンドでは || ですが、時には concat() のような関数にもなります。

String matching

マッチング演算子は常にバックエンド固有であり、異なるデータベースに対して異なる動作と結果を提供する可能性があります。

  • ColumnOperators.match() :

    これは方言固有の演算子で、もし利用可能であれば、基礎となるデータベースのMATCH機能を利用します。:

    >>> print(column("x").match("word"))
    
    x MATCH :x_1
  • ColumnOperators.regexp_match() :

    この演算子は方言特有のもので、例えばPostgreSQLの方言で説明することができます。:

    >>> from sqlalchemy.dialects import postgresql
    >>> print(column("x").regexp_match("word").compile(dialect=postgresql.dialect()))
    
    x ~ %(x_1)s

    Or MySQL:

    >>> from sqlalchemy.dialects import mysql
    >>> print(column("x").regexp_match("word").compile(dialect=mysql.dialect()))
    
    x REGEXP %s

String Alteration

  • ColumnOperators.concat() :

    文字列の連結:

    >>> print(column("x").concat("some string"))
    
    x || :x_1

    この演算子は ColumnOperators.__add__() 、つまりPythonの + 演算子を使って、 String から派生した列式を扱うときに利用できます:

    >>> print(column("x", String) + "some string")
    
    x || :x_1

    この演算子は適切なデータベース固有の構文を生成します。例えばMySQLでは、歴史的には concat() というSQL関数でした。:

    >>> print((column("x", String) + "some string").compile(dialect=mysql.dialect()))
    
    concat(x, %s)
  • ColumnOperators.regexp_replace():

    ColumnOperators.regexp() を補完するもので、これをサポートするバックエンドに対して同等のREGEXP REPLACEを生成します:

    >>> print(column("x").regexp_replace("foo", "bar").compile(dialect=postgresql.dialect()))
    
    REGEXP_REPLACE(x, %(x_1)s, %(x_2)s)
  • ColumnOperators.collate():

    式の実行時に特定の照合を行うCOLLATE SQL演算子を生成します。:

    >>> print(
    ...     (column("x").collate("latin1_german2_ci") == "Müller").compile(
    ...         dialect=mysql.dialect()
    ...     )
    ... )
    
    (x COLLATE latin1_german2_ci) = %s

    リテラル値に対してCOLLATEを使用するには、 literal() 構文を使用します。:

    >>> from sqlalchemy import literal
    >>> print(
    ...     (literal("Müller").collate("latin1_german2_ci") == column("x")).compile(
    ...         dialect=mysql.dialect()
    ...     )
    ... )
    
    (%s COLLATE latin1_german2_ci) = x

Arithmetic Operators

  • ColumnOperators.__add__(), ColumnOperators.__radd__() (Python “+” operator):

    >>> print(column("x") + 5)
    
    x + :x_1
    >>> print(5 + column("x"))
    :x_1 + x

    式のデータ型が String または同様の場合、 ColumnOperators.__add__() 演算子は代わりに string concatenation を生成します。

  • ColumnOperators.__sub__(), ColumnOperators.__rsub__() (Python “-” operator):

    >>> print(column("x") - 5)
    
    x - :x_1
    >>> print(5 - column("x"))
    :x_1 - x
  • ColumnOperators.__mul__(), ColumnOperators.__rmul__() (Python “*” operator):

    >>> print(column("x") * 5)
    
    x * :x_1
    >>> print(5 * column("x"))
    :x_1 * x
  • ColumnOperators.__truediv__(), ColumnOperators.__rtruediv__() (Python “/” operator).

    これはPythonの truediv 演算子で、整数の真の除算が行われることを保証します:

    >>> print(column("x") / 5)
    
    x / CAST(:x_1 AS NUMERIC)
    >>> print(5 / column("x"))
    :x_1 / CAST(x AS NUMERIC)

    Changed in version 2.0: Pythonの / 演算子で、整数の真の除算が確実に行われるようになりました。

  • ColumnOperators.__floordiv__(), ColumnOperators.__rfloordiv__() (Python “//” operator).

    これはPythonの floordiv 演算子で、床の分割が行われることを保証します。デフォルトのバックエンドやPostgreSQLのようなバックエンドでは、SQLの / 演算子は通常整数値に対して次のように動作します。:

    >>> print(column("x") // 5)
    
    x / :x_1
    >>> print(5 // column("x", Integer))
    :x_1 / x

    デフォルトでフロア分割を使用しないバックエンドの場合、または数値とともに使用する場合は、FLOOR()関数を使用してフロア分割を確認します:

    >>> print(column("x") // 5.5)
    
    FLOOR(x / :x_1)
    >>> print(5 // column("x", Numeric))
    FLOOR(:x_1 / x)

    New in version 2.0: FLOOR分割のサポート

  • ColumnOperators.__mod__(), ColumnOperators.__rmod__() (Python “%” operator):

    >>> print(column("x") % 5)
    
    x % :x_1
    >>> print(5 % column("x"))
    :x_1 % x

Bitwise Operators

ビット演算子関数は、整数やビット列(例えばPostgreSQL BIT など)のような互換性のある値に対して動作することが期待される、異なるバックエンドにまたがるビット単位の演算子への統一的なアクセスを提供します。これらは一般的なブール演算子では ない ことに注意してください。

New in version 2.0.2: ビット単位の操作のための専用演算子を追加しました。

  • ColumnOperators.bitwise_not(), bitwise_not().

    親オブジェクトに対してビット否定句を生成するカラムレベルのメソッドとして使用できます。:

    >>> print(column("x").bitwise_not())
    ~x

    この演算子は、個々のカラム式にビット否定を適用するカラム式レベルのメソッドとしても使用できます:

    >>> from sqlalchemy import bitwise_not
    >>> print(bitwise_not(column("x")))
    ~x
  • ColumnOperators.bitwise_and() はビット単位のANDを生成します:

    >>> print(column("x").bitwise_and(5))
    x & :x_1
  • ColumnOperators.bitwise_or() はビット単位のORを生成します:

    >>> print(column("x").bitwise_or(5))
    x | :x_1
  • ColumnOperators.bitwise_xor() はビット単位のXORを生成します:

    >>> print(column("x").bitwise_xor(5))
    x ^ :x_1

    PostgreSQLのダイアレクトでは、”#”はビット単位のXORを表すために使用されます。これは以下のバックエンドのいずれかを使用すると自動的に発生します。

    >>> from sqlalchemy.dialects import postgresql
    >>> print(column("x").bitwise_xor(5).compile(dialect=postgresql.dialect()))
    x # %(x_1)s
  • ColumnOperators.bitwise_rshift(), ColumnOperators.bitwise_lshift()

    ビットシフト演算子を生成します:

    >>> print(column("x").bitwise_rshift(5))
    x >> :x_1
    >>> print(column("x").bitwise_lshift(5))
    x << :x_1

Using Conjunctions and Negations

最も一般的な接続詞である”AND”は、 Select.where() メソッドや、 Update.where()Delete.where() などの同様のメソッドを繰り返し使用すると、自動的に適用されます:

>>> print(
...     select(address_table.c.email_address)
...     .where(user_table.c.name == "squidward")
...     .where(address_table.c.user_id == user_table.c.id)
... )
SELECT address.email_address FROM address, user_account WHERE user_account.name = :name_1 AND address.user_id = user_account.id

Select.where() , Update.where() および Delete.where() も同じ効果を持つ複数の式を受け付けます:

>>> print(
...     select(address_table.c.email_address).where(
...         user_table.c.name == "squidward",
...         address_table.c.user_id == user_table.c.id,
...     )
... )
SELECT address.email_address FROM address, user_account WHERE user_account.name = :name_1 AND address.user_id = user_account.id

and_()or_() 関数を使うと、”AND”接続詞とその対になる”OR”接続詞の両方を直接利用できます:

>>> from sqlalchemy import and_, or_
>>> print(
...     select(address_table.c.email_address).where(
...         and_(
...             or_(user_table.c.name == "squidward", user_table.c.name == "sandy"),
...             address_table.c.user_id == user_table.c.id,
...         )
...     )
... )
SELECT address.email_address FROM address, user_account WHERE (user_account.name = :name_1 OR user_account.name = :name_2) AND address.user_id = user_account.id

否定は not_() 関数を使って行うことができます。これは通常、ブール式の演算子を反転させます:

>>> from sqlalchemy import not_
>>> print(not_(column("x") == 5))
x != :x_1

また、必要に応じて NOT などのキーワードを適用することもできます:

>>> from sqlalchemy import Boolean
>>> print(not_(column("x", Boolean)))
NOT x

Conjunction Operators

上の結合関数 and_(),:func:_sql.or_,:func:_sql.not_ は、オーバーロードされたPython演算子としても利用できます。

  • Operators.__and__() (Python “&” operator):

    Pythonバイナリの & 演算子はオーバーロードされていて、 and_() と同じように動作します(2つのオペランドを囲む括弧に注意してください):

    >>> print((column("x") == 5) & (column("y") == 10))
    
    x = :x_1 AND y = :y_1
  • Operators.__or__() (Python “|” operator):

    Pythonバイナリの | 演算子はオーバーロードされていて、 or_() と同じように動作します(2つのオペランドを囲む括弧に注意してください):

    >>> print((column("x") == 5) | (column("y") == 10))
    
    x = :x_1 OR y = :y_1
  • Operators.__invert__() (Python “~” operator):

    Pythonの二項演算子 ~ は、既存の演算子を反転するか、式全体に NOT キーワードを適用することで、 not_() と同じ動作をするようにオーバーロードされています:

    >>> print(~(column("x") == 5))
    
    x != :x_1
    >>> from sqlalchemy import Boolean >>> print(~column("x", Boolean))
    NOT x