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

implement metadata per bind, refactor entire extension #1087

Merged
merged 27 commits into from Sep 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions .pre-commit-config.yaml
Expand Up @@ -5,17 +5,18 @@ repos:
rev: v2.37.3
hooks:
- id: pyupgrade
args: ["--py36-plus"]
args: ["--py37-plus"]
- repo: https://github.com/asottile/reorder_python_imports
rev: v3.8.2
hooks:
- id: reorder-python-imports
files: "^(?!examples/)"
args: ["--application-directories", "src"]
args: ["--py37-plus", "--application-directories", "src"]
- repo: https://github.com/psf/black
rev: 22.8.0
hooks:
- id: black
args: ["--target-version", "py37"]
- repo: https://github.com/PyCQA/flake8
rev: 5.0.4
hooks:
Expand Down
86 changes: 69 additions & 17 deletions CHANGES.rst
Expand Up @@ -4,25 +4,77 @@ Version 3.0.0
Unreleased

- Drop support for Python 2, 3.4, 3.5, and 3.6.
- Bump minimum version of Flask to 1.0.4.
- Bump minimum version of SQLAlchemy to 1.2.
- Bump minimum version of Flask to 2.2.
- Bump minimum version of SQLAlchemy to 1.4.18.
- Remove previously deprecated code.
- The CamelCase to snake_case table name converter handles more
patterns correctly. If such a name was already created in the
database, either use Alembic to rename the table, or set
``__tablename__`` to keep the old name. :issue:`406`
- Set ``SQLALCHEMY_TRACK_MODIFICATIONS`` to ``False`` by default.
:pr:`727`
- Remove default ``'sqlite:///:memory:'`` setting for
``SQLALCHEMY_DATABASE_URI``, raise error when both it and
``SQLALCHEMY_BINDS`` are unset. :pr:`731`
- Configuring SQLite with a relative path is relative to
``app.instance_path`` instead of ``app.root_path``. The instance
folder is created if necessary. :issue:`462`
- Deprecate ``SQLALCHEMY_COMMIT_ON_TEARDOWN`` as it can cause various
design issues that are difficult to debug. Call
``db.session.commit()`` directly instead. :issue:`216`
- The ``CamelCase`` to ``snake_case`` table name converter handles more patterns
correctly. If such a that was was already created in the database changed, either
use Alembic to rename the table, or set ``__tablename__`` to keep the old name.
:issue:`406`
- Set ``SQLALCHEMY_TRACK_MODIFICATIONS`` to ``False`` by default. :pr:`727`
- Remove default ``'sqlite:///:memory:'`` setting for ``SQLALCHEMY_DATABASE_URI``,
raise error when both it and ``SQLALCHEMY_BINDS`` are unset. :pr:`731`
- Configuring SQLite with a relative path is relative to ``app.instance_path`` instead
of ``app.root_path``. The instance folder is created if necessary. :issue:`462`
- Deprecate ``SQLALCHEMY_COMMIT_ON_TEARDOWN`` as it can cause various design issues
that are difficult to debug. Call ``db.session.commit()`` directly instead.
:issue:`216`
- Change the default MySQL character set to "utf8mb4". :issue:`875`
- ``Pagination``, ``Pagination.iter_pages``, and ``Query.paginate`` parameters are
keyword-only.
- ``Pagination`` is iterable, iterating over its items. :issue:`70`
- ``Pagination.apply_to_query`` can be used instead of ``query.paginate``.
- ``Query.paginate`` ``count`` is more efficient.
- ``Pagination.iter_pages`` is more efficient. :issue:`622`
- ``Pagination.iter_pages`` ``right_current`` parameter is inclusive.
- ``Query`` is renamed from ``BaseQuery``.
- ``Query.one_or_404`` is added.
- ``get_debug_queries`` is renamed to ``get_recorded_queries`` to better match the
config and functionality.
- Recorded query info is a dataclass instead of a tuple. The ``context`` attribute is
renamed to ``location``. Finding the location uses a more inclusive check.
- The ``SQLAlchemy`` extension object uses ``__getattr__`` to alias names from the
SQLAlchemy package, rather than copying them as attributes.
- The query class is applied to ``backref`` in ``relationship``. :issue:`417`
- ``SignallingSession`` is renamed to ``Session``.
- ``Session.get_bind`` more closely matches the base implementation.
- ``Model`` ``repr`` distinguishes between transient and pending instances.
:issue:`967`
- Different bind keys use different SQLAlchemy ``MetaData`` registries, allowing
tables in different databases to have the same name. Bind keys are stored and looked
up on the resulting metadata rather than the model or table.
- The ``engine_options`` parameter is applied as defaults before per-engine
configuration.
- ``SQLALCHEMY_BINDS`` values can either be an engine URL, or a dict of engine options
including URL, for each bind. ``SQLALCHEMY_DATABASE_URI`` and
``SQLALCHEMY_ENGINE_OPTIONS`` correspond to the ``None`` key and take precedence.
:issue:`783`
- Engines are created when calling ``init_app`` rather than the first time they are
accessed. :issue:`698`
- The extension instance is stored directly as ``app.extensions["sqlalchemy"]``.
:issue:`698`
- All parameters except ``app`` are keyword-only.
- Setup methods that create the engines and session are renamed with a leading
underscore. They are considered internal interfaces which may change at any time.
- ``db.Table`` is a subclass instead of a function.
- The session class can be customized by passing the ``class_`` key in the
``session_options`` parameter. :issue:`327`
- SQLite engines do not use ``NullPool`` if ``pool_size`` is 0.
- MySQL engines do not set ``pool_size`` to 10.
- ``db.engines`` exposes the map of bind keys to engines for the current app.
- ``get_engine``, ``get_tables_for_bind``, and ``get_binds`` are deprecated.
- Renamed the ``bind`` parameter to ``bind_key`` and removed the ``app`` parameter
from various methods.
- ``SQLALCHEMY_RECORD_QUERIES`` configuration takes precedence over ``app.debug`` and
``app.testing``, allowing it to be disabled in those modes.
- The session is scoped to the current app context instead of the thread. This
requires that an app context is active. This ensures that the session is cleaned up
after every request.
- A custom model class can implement ``__init_subclass__`` with class parameters.
:issue:`1002`
- An active Flask application context is always required to access ``session`` and
``engine``, regardless of if an application was passed to the constructor.
:issue:`508, 944`


Version 2.5.1
Expand Down
10 changes: 5 additions & 5 deletions CONTRIBUTING.rst
Expand Up @@ -91,7 +91,7 @@ First time setup

.. code-block:: text

$ git clone https://github.com/pallets/flask-sqlalchemy
$ git clone https://github.com/pallets-eco/flask-sqlalchemy
$ cd flask-sqlalchemy

- Add your fork as a remote to push your work to. Replace
Expand Down Expand Up @@ -132,7 +132,7 @@ First time setup
.. _username: https://docs.github.com/en/github/using-git/setting-your-username-in-git
.. _email: https://docs.github.com/en/github/setting-up-and-managing-your-github-user-account/setting-your-commit-email-address
.. _GitHub account: https://github.com/join
.. _Fork: https://github.com/pallets/jinja/fork
.. _Fork: https://github.com/pallets-eco/flask-sqlalchemy/fork
.. _Clone: https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#step-2-create-a-local-clone-of-your-fork


Expand All @@ -146,15 +146,15 @@ Start coding
.. code-block:: text

$ git fetch origin
$ git checkout -b your-branch-name origin/2.x
$ git checkout -b your-branch-name origin/3.0.x

If you're submitting a feature addition or change, branch off of the
"master" branch.
"main" branch.

.. code-block:: text

$ git fetch origin
$ git checkout -b your-branch-name origin/master
$ git checkout -b your-branch-name origin/main

- Using your favorite editor, make your changes,
`committing as you go`_.
Expand Down
6 changes: 3 additions & 3 deletions README.rst
Expand Up @@ -53,7 +53,7 @@ Contributing
For guidance on setting up a development environment and how to make a
contribution to Flask-SQLAlchemy, see the `contributing guidelines`_.

.. _contributing guidelines: https://github.com/pallets/flask-sqlalchemy/blob/master/CONTRIBUTING.rst
.. _contributing guidelines: https://github.com/pallets-eco/flask-sqlalchemy/blob/main/CONTRIBUTING.rst


Donate
Expand All @@ -73,8 +73,8 @@ Links
- Documentation: https://flask-sqlalchemy.palletsprojects.com/
- Changes: https://flask-sqlalchemy.palletsprojects.com/changes/
- PyPI Releases: https://pypi.org/project/Flask-SQLAlchemy/
- Source Code: https://github.com/pallets/flask-sqlalchemy/
- Issue Tracker: https://github.com/pallets/flask-sqlalchemy/issues/
- Source Code: https://github.com/pallets-eco/flask-sqlalchemy/
- Issue Tracker: https://github.com/pallets-eco/flask-sqlalchemy/issues/
- Website: https://palletsprojects.com/
- Twitter: https://twitter.com/PalletsTeam
- Chat: https://discord.gg/pallets
7 changes: 4 additions & 3 deletions docs/Makefile
@@ -1,9 +1,10 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build

Expand Down
81 changes: 61 additions & 20 deletions docs/api.rst
@@ -1,45 +1,86 @@
API
---
===

.. module:: flask_sqlalchemy

Configuration
`````````````
Extension
---------

.. module:: flask_sqlalchemy

.. autoclass:: SQLAlchemy
:members:
:members:


Model
-----

Models
``````
.. module:: flask_sqlalchemy.model

.. autoclass:: Model
:members:

.. attribute:: __bind_key__

Optionally declares the bind to use. ``None`` refers to the default
bind. For more information see :ref:`binds`.
Use this bind key to select a metadata and engine to associate with this model's
table. Ignored if ``metadata`` or ``__table__`` is set. If not given, uses the
default key, ``None``.

.. attribute:: __tablename__

The name of the table in the database. This is required by SQLAlchemy;
however, Flask-SQLAlchemy will set it automatically if a model has a
primary key defined. If the ``__table__`` or ``__tablename__`` is set
explicitly, that will be used instead.
The name of the table in the database. This is required by SQLAlchemy; however,
Flask-SQLAlchemy will set it automatically if a model has a primary key defined.
If the ``__table__`` or ``__tablename__`` is set explicitly, that will be used
instead.

.. autoclass:: DefaultMeta

.. autoclass:: BindMetaMixin

.. autoclass:: NameMetaMixin


Query
-----

.. module:: flask_sqlalchemy.query

.. autoclass:: BaseQuery
.. autoclass:: Query
:members:

Sessions
````````

.. autoclass:: SignallingSession
Session
-------

.. module:: flask_sqlalchemy.session

.. autoclass:: Session
:members:

Utilities
`````````

Pagination
----------

.. module:: flask_sqlalchemy.pagination

.. autoclass:: Pagination
:members:

.. autofunction:: get_debug_queries

Record Queries
--------------

.. module:: flask_sqlalchemy.record_queries

.. autofunction:: get_recorded_queries


Track Modifications
-------------------

.. module:: flask_sqlalchemy.track_modifications

.. autodata:: models_committed
:no-value:

.. autodata:: before_models_committed
:no-value: