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

bpo-45677: Reword first section of sqlite3 docs #29326

Merged
merged 14 commits into from
Nov 15, 2021
35 changes: 17 additions & 18 deletions Doc/library/sqlite3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ 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`, and
requires SQLite 3.7.15 or newer.

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.
Use the special path name ``:memory:`` to create a temporary database in RAM.

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

cur = con.cursor()

Expand All @@ -49,16 +49,16 @@ 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 and is available in subsequent sessions::

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 @@ -73,27 +73,26 @@ 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 will usually need to use values from Python variables. It is not
adviced to assemble queries using Python's string operations, because they are
vulnerable to an 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
Instead, use the DB-API's parameter substitution by putting placeholders in the
query string. Provide the actual values as a :class:`tuple` as the second
argument to 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
10 changes: 5 additions & 5 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
in-memory database:
Use the special path name ":memory:" 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:
Now, create a Cursor object and call its execute() method to perform SQL
queries:

cu = cx.cursor()

Expand Down