geometry of a "schema" takes many forms, including names of "schemas" under the
scope of a particular database (e.g. PostgreSQL schemas), named sibling
databases (e.g. MySQL / MariaDB access to other databases on the same server),
-as well as other concepts like tables owned by other usernames (Oracle, SQL
-Server) or even names that refer to alternate database files (SQLite ATTACH) or
-remote servers (Oracle DBLINK with synonyms).
+as well as other concepts like tables owned by other usernames (Oracle
+Database, SQL Server) or even names that refer to alternate database files
+(SQLite ATTACH) or remote servers (Oracle Database DBLINK with synonyms).
What all of the above approaches have (mostly) in common is that there's a way
of referencing this alternate set of tables using a string name. SQLAlchemy
"database" that typically has a single "owner". Within this database there
can be any number of "schemas" which then contain the actual table objects.
- A table within a specific schema is referenced explicitly using the
- syntax "<schemaname>.<tablename>". Contrast this to an architecture such
- as that of MySQL, where there are only "databases", however SQL statements
- can refer to multiple databases at once, using the same syntax except it
- is "<database>.<tablename>". On Oracle, this syntax refers to yet another
- concept, the "owner" of a table. Regardless of which kind of database is
- in use, SQLAlchemy uses the phrase "schema" to refer to the qualifying
- identifier within the general syntax of "<qualifier>.<tablename>".
+ A table within a specific schema is referenced explicitly using the syntax
+ "<schemaname>.<tablename>". Contrast this to an architecture such as that
+ of MySQL, where there are only "databases", however SQL statements can
+ refer to multiple databases at once, using the same syntax except it is
+ "<database>.<tablename>". On Oracle Database, this syntax refers to yet
+ another concept, the "owner" of a table. Regardless of which kind of
+ database is in use, SQLAlchemy uses the phrase "schema" to refer to the
+ qualifying identifier within the general syntax of
+ "<qualifier>.<tablename>".
.. seealso::
to a PostgreSQL database, the default "schema" is called "public".
There are often cases where the default "schema" cannot be set via the login
-itself and instead would usefully be configured each time a connection
-is made, using a statement such as "SET SEARCH_PATH" on PostgreSQL or
-"ALTER SESSION" on Oracle. These approaches may be achieved by using
-the :meth:`_pool.PoolEvents.connect` event, which allows access to the
-DBAPI connection when it is first created. For example, to set the
-Oracle CURRENT_SCHEMA variable to an alternate name::
+itself and instead would usefully be configured each time a connection is made,
+using a statement such as "SET SEARCH_PATH" on PostgreSQL or "ALTER SESSION" on
+Oracle Database. These approaches may be achieved by using the
+:meth:`_pool.PoolEvents.connect` event, which allows access to the DBAPI
+connection when it is first created. For example, to set the Oracle Database
+CURRENT_SCHEMA variable to an alternate name::
from sqlalchemy import event
from sqlalchemy import create_engine
- engine = create_engine("oracle+cx_oracle://scott:tiger@tsn_name")
+ engine = create_engine(
+ "oracle+oracledb://scott:tiger@localhost:1521?service_name=freepdb1"
+ )
@event.listens_for(engine, "connect", insert=True)
isolation_level="AUTOCOMMIT"
)
-For ``READ COMMITTED`` and ``SERIALIZABLE``, the Oracle dialects sets the level
-at the session level using ``ALTER SESSION``, which is reverted back to its
-default setting when the connection is returned to the connection pool.
+For ``READ COMMITTED`` and ``SERIALIZABLE``, the Oracle Database dialects sets
+the level at the session level using ``ALTER SESSION``, which is reverted back
+to its default setting when the connection is returned to the connection pool.
Valid values for ``isolation_level`` include:
.. note:: The implementation for the
:meth:`_engine.Connection.get_isolation_level` method as implemented by the
- Oracle dialects necessarily force the start of a transaction using the
- Oracle Database DBMS_TRANSACTION.LOCAL_TRANSACTION_ID function; otherwise no
- level is normally readable.
+ Oracle Database dialects necessarily force the start of a transaction using
+ the Oracle Database DBMS_TRANSACTION.LOCAL_TRANSACTION_ID function;
+ otherwise no level is normally readable.
Additionally, the :meth:`_engine.Connection.get_isolation_level` method will
raise an exception if the ``v$transaction`` view is not available due to
In Oracle Database, the data dictionary represents all case insensitive
identifier names using UPPERCASE text. SQLAlchemy on the other hand considers
-an all-lower case identifier name to be case insensitive. The Oracle dialects
-convert all case insensitive identifiers to and from those two formats during
-schema level communication, such as reflection of tables and indexes. Using an
-UPPERCASE name on the SQLAlchemy side indicates a case sensitive identifier,
-and SQLAlchemy will quote the name - this will cause mismatches against data
-dictionary data received from Oracle, so unless identifier names have been
-truly created as case sensitive (i.e. using quoted names), all lowercase names
-should be used on the SQLAlchemy side.
+an all-lower case identifier name to be case insensitive. The Oracle Database
+dialects convert all case insensitive identifiers to and from those two formats
+during schema level communication, such as reflection of tables and indexes.
+Using an UPPERCASE name on the SQLAlchemy side indicates a case sensitive
+identifier, and SQLAlchemy will quote the name - this will cause mismatches
+against data dictionary data received from Oracle Database, so unless
+identifier names have been truly created as case sensitive (i.e. using quoted
+names), all lowercase names should be used on the SQLAlchemy side.
.. _oracle_max_identifier_lengths:
statement like UNION. This syntax is also available directly by using the
:meth:`_sql.Select.fetch` method.
-.. versionchanged:: 2.0 the Oracle dialect now uses
- ``FETCH FIRST N ROW / OFFSET N ROWS`` for all
- :meth:`_sql.Select.limit` and :meth:`_sql.Select.offset` usage including
- within the ORM and legacy :class:`_orm.Query`. To force the legacy
- behavior using window functions, specify the ``enable_offset_fetch=False``
- dialect parameter to :func:`_sa.create_engine`.
+.. versionchanged:: 2.0 the Oracle Database dialects now use ``FETCH FIRST N
+ ROW / OFFSET N ROWS`` for all :meth:`_sql.Select.limit` and
+ :meth:`_sql.Select.offset` usage including within the ORM and legacy
+ :class:`_orm.Query`. To force the legacy behavior using window functions,
+ specify the ``enable_offset_fetch=False`` dialect parameter to
+ :func:`_sa.create_engine`.
The use of ``FETCH FIRST / OFFSET`` may be disabled on any Oracle Database
version by passing ``enable_offset_fetch=False`` to :func:`_sa.create_engine`,
This mode is also selected automatically when using a version of Oracle
Database prior to 12c.
-When using legacy mode, or when a :class:`.Select` statement
-with limit/offset is embedded in a compound statement, an emulated approach for
-LIMIT / OFFSET based on window functions is used, which involves creation of a
-subquery using ``ROW_NUMBER`` that is prone to performance issues as well as
-SQL construction issues for complex statements. However, this approach is
-supported by all Oracle versions. See notes below.
+When using legacy mode, or when a :class:`.Select` statement with limit/offset
+is embedded in a compound statement, an emulated approach for LIMIT / OFFSET
+based on window functions is used, which involves creation of a subquery using
+``ROW_NUMBER`` that is prone to performance issues as well as SQL construction
+issues for complex statements. However, this approach is supported by all
+Oracle Database versions. See notes below.
Notes on LIMIT / OFFSET emulation (when fetch() method cannot be used)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
to :func:`_sa.create_engine`.
.. versionchanged:: 1.4
- The Oracle dialect renders limit/offset integer values using a "post
- compile" scheme which renders the integer directly before passing the
- statement to the cursor for execution. The ``use_binds_for_limits`` flag
- no longer has an effect.
+
+ The Oracle Database dialect renders limit/offset integer values using a
+ "post compile" scheme which renders the integer directly before passing
+ the statement to the cursor for execution. The ``use_binds_for_limits``
+ flag no longer has an effect.
.. seealso::
When this flag is set, the given name (such as ``some_table`` above) will be
searched not just in the ``ALL_TABLES`` view, but also within the
``ALL_SYNONYMS`` view to see if this name is actually a synonym to another
-name. If the synonym is located and refers to a DBLINK, the Oracle dialects
-know how to locate the table's information using DBLINK syntax(e.g.
+name. If the synonym is located and refers to a DBLINK, the Oracle Database
+dialects know how to locate the table's information using DBLINK syntax(e.g.
``@dblink``).
``oracle_resolve_synonyms`` is accepted wherever reflection arguments are
Constraint Reflection
---------------------
-The Oracle dialects can return information about foreign key, unique, and CHECK
-constraints, as well as indexes on tables.
+The Oracle Database dialects can return information about foreign key, unique,
+and CHECK constraints, as well as indexes on tables.
Raw information regarding these constraints can be acquired using
:meth:`_reflection.Inspector.get_foreign_keys`,
:meth:`_reflection.Inspector.get_check_constraints`, and
:meth:`_reflection.Inspector.get_indexes`.
-.. versionchanged:: 1.2 The Oracle dialect can now reflect UNIQUE and
+.. versionchanged:: 1.2 The Oracle Database dialect can now reflect UNIQUE and
CHECK constraints.
When using reflection at the :class:`_schema.Table` level, the
Note the following caveats:
* When using the :meth:`_reflection.Inspector.get_check_constraints` method,
- Oracle dialects build a special "IS NOT NULL" constraint for columns that
- specify "NOT NULL". This constraint is **not** returned by default; to
+ Oracle Database dialects build a special "IS NOT NULL" constraint for columns
+ that specify "NOT NULL". This constraint is **not** returned by default; to
include the "IS NOT NULL" constraints, pass the flag ``include_all=True``::
from sqlalchemy import create_engine, inspect
- engine = create_engine("oracle+cx_oracle://s:t@dsn")
+ engine = create_engine("oracle+oracledb://scott:tiger@localhost:1521?service_name=freepdb1")
inspector = inspect(engine)
all_check_constraints = inspector.get_check_constraints(
"some_table", include_all=True)
-* in most cases, when reflecting a :class:`_schema.Table`,
- a UNIQUE constraint will
- **not** be available as a :class:`.UniqueConstraint` object, as Oracle
- mirrors unique constraints with a UNIQUE index in most cases (the exception
- seems to be when two or more unique constraints represent the same columns);
- the :class:`_schema.Table` will instead represent these using
- :class:`.Index`
- with the ``unique=True`` flag set.
+* in most cases, when reflecting a :class:`_schema.Table`, a UNIQUE constraint
+ will **not** be available as a :class:`.UniqueConstraint` object, as Oracle
+ Database mirrors unique constraints with a UNIQUE index in most cases (the
+ exception seems to be when two or more unique constraints represent the same
+ columns); the :class:`_schema.Table` will instead represent these using
+ :class:`.Index` with the ``unique=True`` flag set.
* Oracle Database creates an implicit index for the primary key of a table;
this index is **excluded** from all index results.
Oracle Database has no datatype known as ``DATETIME``, it instead has only
``DATE``, which can actually store a date and time value. For this reason, the
-Oracle dialects provide a type :class:`_oracle.DATE` which is a subclass of
-:class:`.DateTime`. This type has no special behavior, and is only present as
-a "marker" for this type; additionally, when a database column is reflected and
-the type is reported as ``DATE``, the time-supporting :class:`_oracle.DATE`
-type is used.
+Oracle Database dialects provide a type :class:`_oracle.DATE` which is a
+subclass of :class:`.DateTime`. This type has no special behavior, and is only
+present as a "marker" for this type; additionally, when a database column is
+reflected and the type is reported as ``DATE``, the time-supporting
+:class:`_oracle.DATE` type is used.
.. _oracle_table_options:
Oracle Database Table Options
-----------------------------
-The CREATE TABLE phrase supports the following options with Oracle dialects in
-conjunction with the :class:`_schema.Table` construct:
+The CREATE TABLE phrase supports the following options with Oracle Database
+dialects in conjunction with the :class:`_schema.Table` construct:
* ``ON COMMIT``::