Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.9] bpo-45677: Reword first section of sqlite3 docs (GH-29326) #29567

Merged
merged 1 commit into from
Nov 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 20 additions & 18 deletions Doc/library/sqlite3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ PostgreSQL or Oracle.
The sqlite3 module was written by Gerhard Häring. It provides a SQL interface
compliant with the DB-API 2.0 specification described by :pep:`249`.

To use the module, you must first create a :class:`Connection` object that
To use the module, start by creating a :class:`Connection` object that
represents the database. Here the data will be stored in the
:file:`example.db` file::

import sqlite3
con = sqlite3.connect('example.db')

You can also supply the special name ``:memory:`` to create a database in RAM.
The special path name ``:memory:`` can be provided to create a temporary
database in RAM.

Once you have a :class:`Connection`, you can create a :class:`Cursor` object
Once a :class:`Connection` has been established, create a :class:`Cursor` object
and call its :meth:`~Cursor.execute` method to perform SQL commands::

cur = con.cursor()
Expand All @@ -48,16 +49,17 @@ and call its :meth:`~Cursor.execute` method to perform SQL commands::
# Just be sure any changes have been committed or they will be lost.
con.close()

The data you've saved is persistent and is available in subsequent sessions::
The saved data is persistent: it can be reloaded in a subsequent session even
after restarting the Python interpreter::

import sqlite3
con = sqlite3.connect('example.db')
cur = con.cursor()

To retrieve data after executing a SELECT statement, you can either treat the
cursor as an :term:`iterator`, call the cursor's :meth:`~Cursor.fetchone` method to
retrieve a single matching row, or call :meth:`~Cursor.fetchall` to get a list of the
matching rows.
To retrieve data after executing a SELECT statement, either treat the cursor as
an :term:`iterator`, call the cursor's :meth:`~Cursor.fetchone` method to
retrieve a single matching row, or call :meth:`~Cursor.fetchall` to get a list
of the matching rows.

This example uses the iterator form::

Expand All @@ -72,27 +74,27 @@ This example uses the iterator form::

.. _sqlite3-placeholders:

Usually your SQL operations will need to use values from Python variables. You
shouldn't assemble your query using Python's string operations because doing so
is insecure; it makes your program vulnerable to an SQL injection attack
(see the `xkcd webcomic <https://xkcd.com/327/>`_ for a humorous example of
what can go wrong)::
SQL operations usually need to use values from Python variables. However,
beware of using Python's string operations to assemble queries, as they
are vulnerable to SQL injection attacks (see the `xkcd webcomic
<https://xkcd.com/327/>`_ for a humorous example of what can go wrong)::

# Never do this -- insecure!
symbol = 'RHAT'
cur.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)

Instead, use the DB-API's parameter substitution. Put a placeholder wherever
you want to use a value, and then provide a tuple of values as the second
argument to the cursor's :meth:`~Cursor.execute` method. An SQL statement may
Instead, use the DB-API's parameter substitution. To insert a variable into a
query string, use a placeholder in the string, and substitute the actual values
into the query by providing them as a :class:`tuple` of values to the second
argument of the cursor's :meth:`~Cursor.execute` method. An SQL statement may
use one of two kinds of placeholders: question marks (qmark style) or named
placeholders (named style). For the qmark style, ``parameters`` must be a
:term:`sequence <sequence>`. For the named style, it can be either a
:term:`sequence <sequence>` or :class:`dict` instance. The length of the
:term:`sequence <sequence>` must match the number of placeholders, or a
:exc:`ProgrammingError` is raised. If a :class:`dict` is given, it must contain
keys for all named parameters. Any extra items are ignored. Here's an example
of both styles:
keys for all named parameters. Any extra items are ignored. Here's an example of
both styles:

.. literalinclude:: ../includes/sqlite3/execute_1.py

Expand Down
8 changes: 4 additions & 4 deletions Lib/sqlite3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,18 @@
The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compilant
interface to the SQLite library, and requires SQLite 3.7.15 or newer.

To use the module, you must first create a database Connection object:
To use the module, start by creating a database Connection object:

import sqlite3
cx = sqlite3.connect("test.db") # test.db will be created or opened

You can also use the special database name ":memory:" to connect to a transient
The special path name ":memory:" can be provided to connect to a transient
in-memory database:

cx = sqlite3.connect(":memory:") # connect to a database in RAM

Once you have a Connection object, you can create a Cursor object and call its
execute() method to perform SQL queries:
Once a connection has been established, create a Cursor object and call
its execute() method to perform SQL queries:

cu = cx.cursor()

Expand Down