.. _tutorial_core_insert:
-Inserting Rows with Core
--------------------------
+Inserting Rows with ``Insert()`` Constructs
+-------------------------------------------
-When using Core, a SQL INSERT statement is generated using the
-:func:`_sql.insert` function - this function generates a new instance of
-:class:`_sql.Insert` which represents an INSERT statement in SQL, that adds
-new data into a table.
+When using Core as well as within some ORM use cases, a SQL INSERT statement is
+generated directly using the :func:`_sql.insert` function - this function
+generates a new instance of :class:`_sql.Insert` which represents an INSERT
+statement in SQL, that adds new data into a table.
.. container:: orm-header
- **ORM Readers** - The way that rows are INSERTed into the database from an ORM
- perspective makes use of object-centric APIs on the :class:`_orm.Session` object known as the
- :term:`unit of work` process,
- and is fairly different from the Core-only approach described here.
- The more ORM-focused sections later starting at :ref:`tutorial_inserting_orm`
- subsequent to the Expression Language sections introduce this.
+ **ORM Readers** -
+
+ The ORM's means of generating INSERT statements is described in
+ one of two ways; the most common is by using
+ the :term:`unit of work` process which automates the generation of
+ INSERT statements from object state, and is introduced
+ at :ref:`tutorial_inserting_orm`. The other is by using
+ the :class:`_sql.Insert` construct directly
+ in a manner very similar to that described in this section; this use
+ is introduced at :ref:`tutorial_orm_bulk`.
+
The insert() SQL Expression Construct
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The RETURNING feature is also supported by UPDATE and DELETE statements,
which will be introduced later in this tutorial.
- The RETURNING feature is generally [1]_ only
- supported for statement executions that use a single set of bound
- parameters; that is, it won't work with the "executemany" form introduced
- at :ref:`tutorial_multiple_parameters`. Additionally, some dialects
- such as the Oracle dialect only allow RETURNING to return a single row
- overall, meaning it won't work with "INSERT..FROM SELECT" nor will it
- work with multiple row :class:`_sql.Update` or :class:`_sql.Delete`
- forms.
-
- .. [1] There is internal support for the
- :mod:`_postgresql.psycopg2` dialect to INSERT many rows at once
- and also support RETURNING, which is leveraged by the SQLAlchemy
- ORM. However this feature has not been generalized to all dialects
- and is not yet part of SQLAlchemy's regular API.
+ For INSERT statements, the RETURNING feature may be used
+ both for single-row statements as well as for statements that INSERT
+ multiple rows at once. Support for multiple-row INSERT with RETURNING
+ is dialect specific, however is supported for all the dialects
+ that are included in SQLAlchemy which support RETURNING. See the section
+ :ref:`engine_insertmanyvalues` for background on this feature.
.. seealso::
As with other sections, Core users can skip the ORM sections, but ORM users
would best be familiar with these objects from both perspectives.
+ The :class:`.Table` object discussed here is declared in a more indirect
+ (and also fully Python-typed) way when using the ORM, however there is still
+ a :class:`.Table` object within the ORM's configuration.
.. rst-class:: core-header
Setting up MetaData with Table objects
---------------------------------------
-When we work with a relational database, the basic structure that we create and
-query from is known as a **table**. In SQLAlchemy, the "table" is represented
-by a Python object similarly named :class:`_schema.Table`.
+When we work with a relational database, the basic data-holding structure
+in the database which we query from is known a **table**.
+In SQLAlchemy, the database "table" may be represented
+directly by a Python object similarly named :class:`_schema.Table`.
To start using the SQLAlchemy Expression Language,
we will want to have :class:`_schema.Table` objects constructed that represent
:class:`_schema.Table` may be **declared**, meaning we explicitly spell out
in source code what the table looks like, or may be **reflected**, which means
we generate the object based on what's already present in a particular database.
-The two approaches can also be blended in many ways.
+The two approaches can also be blended in many ways, and also interact with
+ORM-centric styles of table declaration.
Whether we will declare or reflect our tables, we start out with a collection
that will be where we place our tables known as the :class:`_schema.MetaData`
Emitting DDL to the Database
----------------------------
-We've constructed a fairly elaborate object hierarchy to represent
-two database tables, starting at the root :class:`_schema.MetaData`
+We've constructed a an object structure that represents
+two database tables in a database, starting at the root :class:`_schema.MetaData`
object, then into two :class:`_schema.Table` objects, each of which hold
onto a collection of :class:`_schema.Column` and :class:`_schema.Constraint`
objects. This object structure will be at the center of most operations