Pull request #41 from kallithea-incoming#default

Title: Move to Alembic for database migrations (v2) (Closed)

This PR:
- removes SQLAlchemy Migrate database migration library
- removes remaining RhodeCode compatibility
- adds basic Alembic database migration support
- in a related move, also upgrades to SQLAlchemy 1.0 and adds well-defined key/index/constraint naming (for new databases only...)

The changesets marked [0.4] are (more or less) ready and proposed for inclusion in the upcoming 0.4 release. Even though they don't contain complete Alembic support, and do not actually define any Alembic migration scripts, they lay the necessary foundation for "going full Alembic" down the road.

In particular, they contain the necessary tweaks to Kallithea config .ini files, such that any Kallithea install made post 0.4 should "just work". Older installs will have to tweak their config as detailed in the docs.

Remaining work (beyond the marked WIP changesets):
- Tests, tests, tests.
- Determine Alembic best practices, so we can start accepting database changes.
- Use Alembic to clean up old cruft in the database.

I recommend reviewing individual changesets.

This is a new iteration of a previous PR, to take PR feedback into account:
https://kallithea-scm.org/repos/kallithea/pull-request/40

Changes since last PR:
https://kallithea-scm.org/repos/kallithea-incoming/compare/rev@ec8500b42712...rev@951248761e43?other_repo=kallithea-incoming
Closed, Under review
hg pull https://kallithea-scm.org/repos/kallithea-incoming -r 951248761e43
2016-05-20 14:49:28
Søren Løvborg (kwi)
sorenl@unity3d.com

This pull request has been closed and can not be updated.

Reviewers

Potential Reviewers

Click to add the repository owner as reviewer:
Pull Request Content
5 comments (0 inline, 5 general) First comment
Showing 13 commits
13 kwi 951248761e43
9 years ago
4 Extinct Draft default
12 kwi bdaecf79a6fb
9 years ago
11 kwi 1327582c9af5
9 years ago
2 Extinct Draft default
10 kwi 08b57807cb24
9 years ago
Extinct Draft default
9 kwi 01bf1b9a2c37
9 years ago
8 kwi 16c36d73e993
9 years ago
1 Extinct Draft default
7 kwi 28acc1d56a8a
9 years ago
Extinct Draft default
6 kwi 0bb267c2d5ab
9 years ago
Extinct Draft default
5 kwi bd333df2742f
9 years ago
Extinct Draft default
4 kwi a7ec1039974f
9 years ago
Extinct Draft default
3 kwi 805a27107d99
9 years ago
2 kwi e4b6c86aa5e2
9 years ago
1 kwi ebd68713988b
9 years ago
6 Extinct Draft default
Common ancestor: 96779dba8b01
74 files changed:
LICENSE.md
12
13
Changeset was too big and was cut off... Show full diff anyway
LICENSE.md
Show inline comments
 
@@ -22,6 +22,18 @@ Various third-party code under GPLv3-com
 
of Kallithea.
 

	
 

	
 
Alembic
 
-------
 

	
 
Kallithea incorporates an [Alembic](https://alembic.readthedocs.org/en/latest/)
 
environment in `kallithea/alembic`, portions of which is:
 

	
 
Copyright © 2009-2016 by Michael Bayer.
 
Alembic is a trademark of Michael Bayer.
 

	
 
and licensed under the MIT-permissive license, which is
 
[included in this distribution](MIT-Permissive-License.txt).
 

	
 

	
 
Bootstrap
 
---------
 
@@ -241,19 +253,6 @@ in this distribution.
 

	
 

	
 

	
 
Migrate
 
-------
 

	
 
Kallithea incorporates in kallithea/lib/dbmigrate/migrate parts of the Python
 
system called [Migrate or sqlalchemy-migrate](https://github.com/stackforge/sqlalchemy-migrate),
 
which is:
 

	
 
Copyright (c) 2009 Evan Rosson, Jan Dittberner, Domen Kožar
 

	
 
and licensed under the MIT-permissive license, which is
 
[included in this distribution](MIT-Permissive-License.txt).
 

	
 

	
 
Icon fonts
 
----------
 

	
MANIFEST.in
Show inline comments
 
@@ -8,11 +8,11 @@ include           README.rst
 
include           development.ini
 
recursive-include docs *
 
recursive-include init.d *
 
recursive-include kallithea/alembic *
 
include           kallithea/bin/ldap_sync.conf
 
include           kallithea/bin/template.ini.mako
 
include           kallithea/config/deployment.ini_tmpl
 
recursive-include kallithea/i18n *
 
recursive-include kallithea/lib/dbmigrate *.py_tmpl README migrate.cfg
 
recursive-include kallithea/public *
 
recursive-include kallithea/templates *
 
recursive-include kallithea/tests/fixtures *
README.rst
Show inline comments
 
@@ -162,76 +162,14 @@ You can also build the documentation loc
 
          install it via the command: ``pip install sphinx`` .
 

	
 

	
 
Converting from RhodeCode
 
-------------------------
 

	
 
Currently, you have two options for working with an existing RhodeCode
 
database:
 

	
 
- keep the database unconverted (intended for testing and evaluation)
 
- convert the database in a one-time step
 

	
 
Maintaining interoperability
 
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 

	
 
Interoperability with RhodeCode 2.2.X installations is provided so you don't
 
have to immediately commit to switching to Kallithea. This option will most
 
likely go away once the two projects have diverged significantly.
 

	
 
To run Kallithea on a RhodeCode database, run::
 

	
 
   echo "BRAND = 'rhodecode'" > kallithea/brand.py
 

	
 
This location will depend on where you installed Kallithea. If you installed
 
via::
 

	
 
   python2 setup.py install
 

	
 
then you will find this location at
 
``$VIRTUAL_ENV/lib/python2.7/site-packages/Kallithea-0.1-py2.7.egg/kallithea``.
 

	
 
One-time conversion
 
^^^^^^^^^^^^^^^^^^^
 
Migrating from RhodeCode
 
------------------------
 

	
 
Alternatively, if you would like to convert the database for good, you can use
 
a helper script provided by Kallithea. This script will operate directly on the
 
database, using the database string you can find in your ``production.ini`` (or
 
``development.ini``) file. For example, if using SQLite::
 

	
 
   cd /path/to/kallithea
 
   cp /path/to/rhodecode/rhodecode.db kallithea.db
 
   pip install sqlalchemy-migrate
 
   python2 kallithea/bin/rebranddb.py sqlite:///kallithea.db
 

	
 
.. Note::
 

	
 
   If you started out using the branding interoperability approach mentioned
 
   above, watch out for stray brand.pyc after removing brand.py.
 

	
 
Git hooks
 
^^^^^^^^^
 

	
 
After switching to Kallithea, it will be necessary to update the Git_ hooks in
 
your repositories. If not, the Git_ hooks from RhodeCode will still be called,
 
which will cause ``git push`` to fail every time.
 

	
 
If you do not have any custom Git_ hooks deployed, perform the following steps
 
(this may take some time depending on the number and size of repositories you
 
have):
 

	
 
1. Log-in as an administrator.
 

	
 
2. Open page *Admin > Settings > Remap and Rescan*.
 

	
 
3. Turn on the option **Install Git Hooks**.
 

	
 
4. Turn on the option **Overwrite existing Git hooks**.
 

	
 
5. Click on the button **Rescan Repositories**.
 

	
 
If you do have custom hooks, you will need to merge those changes manually. In
 
order to get sample hooks from Kallithea, the easiest way is to create a new Git_
 
repository, and have a look at the hooks deployed there.
 
Kallithea 0.3.x and earlier supports migrating from an existing RhodeCode
 
installation. To migrate, install the latest Kallithea 0.3.x and follow
 
the instructions in the 0.3.x README to perform a one-time conversion of
 
the database from RhodeCode to Kallithea, before upgrading to this
 
version of Kallithea.
 

	
 

	
 
.. _virtualenv: http://pypi.python.org/pypi/virtualenv
development.ini
Show inline comments
 
@@ -502,11 +502,18 @@ sqlalchemy.db1.echo = false
 
sqlalchemy.db1.pool_recycle = 3600
 

	
 
################################
 
### ALEMBIC CONFIGURATION   ####
 
################################
 

	
 
[alembic]
 
script_location = kallithea:alembic
 

	
 
################################
 
### LOGGING CONFIGURATION   ####
 
################################
 

	
 
[loggers]
 
keys = root, routes, kallithea, sqlalchemy, beaker, templates, whoosh_indexer
 
keys = root, routes, kallithea, sqlalchemy, alembic, beaker, templates, whoosh_indexer
 

	
 
[handlers]
 
keys = console, console_sql
 
@@ -553,6 +560,11 @@ handlers = console_sql
 
qualname = sqlalchemy.engine
 
propagate = 0
 

	
 
[logger_alembic]
 
level = INFO
 
handlers =
 
qualname = alembic
 

	
 
[logger_whoosh_indexer]
 
level = DEBUG
 
handlers =
docs/dev/dbmigrations.rst
Show inline comments
 
new file 100644
 
=======================
 
Database schema changes
 
=======================
 

	
 
Kallithea uses Alembic for :ref:`database upgrades and downgrades <dbmigrations>`.
 

	
 
If you are developing a Kallithea feature that requires database schema
 
changes, you should make a matching Alembic database migration script:
 

	
 
1. Make your code changes (including database schema changes in ``db.py``).
 

	
 
2. Using a database that has *not* been upgraded, you can auto-generate
 
   a draft Alembic script that will upgrade a database to match the code::
 

	
 
    alembic -c my.ini revision -m "area: add cool feature" --autogenerate
 

	
 
3. Edit the script to clean it up and fix any problems (e.g. remove
 
   ``sqlite_sequence`` changes).
 

	
 
4. Run ``alembic upgrade`` to apply changes to the database.
 

	
 
The Alembic migration script should be committed in the same revision as
 
the database schema (``db.py``) changes.
 

	
 
Assuming your changes are eventually included in the Kallithea mainline,
 
the script's ``down_revision`` ("Revises") will at that point need to be
 
updated to match the linear mainline history.
 

	
 
See the `Alembic documentation`__ for more information, in particular
 
the tutorial and the section about auto-generating migration scripts.
 

	
 
.. __: https://alembic.readthedocs.io/en/latest/
docs/index.rst
Show inline comments
 
@@ -23,6 +23,7 @@ Kallithea Documentation
 
   installation_iis
 
   setup
 
   installation_puppet
 
   upgrade
 

	
 
**Usage**
 

	
 
@@ -52,6 +53,7 @@ Kallithea Documentation
 
   :maxdepth: 1
 

	
 
   contributing
 
   dev/dbmigrations
 
   changelog
 

	
 
**API**
docs/installation.rst
Show inline comments
 
@@ -45,9 +45,6 @@ repository, follow the instructions belo
 

	
 
You can now proceed to :ref:`setup`.
 

	
 
To upgrade, simply update the repository with ``hg pull -u`` and restart the
 
server.
 

	
 
.. _installation-virtualenv:
 

	
 

	
 
@@ -123,90 +120,5 @@ To install as a regular user in ``~/.loc
 
You can now proceed to :ref:`setup`.
 

	
 

	
 
Upgrading Kallithea from Python Package Index (PyPI)
 
----------------------------------------------------
 

	
 
.. note::
 
   It is strongly recommended that you **always** perform a database and
 
   configuration backup before doing an upgrade.
 

	
 
   These directions will use '{version}' to note that this is the version of
 
   Kallithea that these files were used with.  If backing up your Kallithea
 
   instance from version 0.1 to 0.2, the ``my.ini`` file could be
 
   backed up to ``my.ini.0-1``.
 

	
 
If using a SQLite database, stop the Kallithea process/daemon/service, and
 
then make a copy of the database file::
 

	
 
 service kallithea stop
 
 cp kallithea.db kallithea.db.{version}
 

	
 
Back up your configuration file::
 

	
 
 cp my.ini my.ini.{version}
 

	
 
Ensure that you are using the Python virtual environment that you originally
 
installed Kallithea in by running::
 

	
 
 pip freeze
 

	
 
This will list all packages installed in the current environment.  If
 
Kallithea isn't listed, activate the correct virtual environment::
 

	
 
 source /srv/kallithea/venv/bin/activate
 

	
 
Once you have verified the environment you can upgrade Kallithea with::
 

	
 
 pip install --upgrade kallithea
 

	
 
Then run the following command from the installation directory::
 

	
 
 paster make-config Kallithea my.ini
 

	
 
This will display any changes made by the new version of Kallithea to your
 
current configuration. It will try to perform an automerge. It is recommended
 
that you recheck the content after the automerge.
 

	
 
.. note::
 
   Please always make sure your .ini files are up to date. Errors can
 
   often be caused by missing parameters added in new versions.
 

	
 
It is also recommended that you rebuild the whoosh index after upgrading since
 
the new whoosh version could introduce some incompatible index changes. Please
 
read the changelog to see if there were any changes to whoosh.
 

	
 
The final step is to upgrade the database. To do this simply run::
 

	
 
 paster upgrade-db my.ini
 

	
 
This will upgrade the schema and update some of the defaults in the database,
 
and will always recheck the settings of the application, if there are no new
 
options that need to be set.
 

	
 
.. note::
 
   The DB schema upgrade library has some limitations and can sometimes fail if you try to
 
   upgrade from older major releases. In such a case simply run upgrades sequentially, e.g.,
 
   upgrading from 0.1.X to 0.3.X should be done like this: 0.1.X. > 0.2.X > 0.3.X
 
   You can always specify what version of Kallithea you want to install for example in pip
 
   `pip install Kallithea==0.2`
 

	
 
You may find it helpful to clear out your log file so that new errors are
 
readily apparent::
 

	
 
 echo > kallithea.log
 

	
 
Once that is complete, you may now start your upgraded Kallithea Instance::
 

	
 
 service kallithea start
 

	
 
Or::
 

	
 
 paster serve /srv/kallithea/my.ini
 

	
 
.. note::
 
   If you're using Celery, make sure you restart all instances of it after
 
   upgrade.
 

	
 

	
 
.. _virtualenv: http://pypi.python.org/pypi/virtualenv
 
.. _pylons: http://www.pylonsproject.org/
docs/installation_win.rst
Show inline comments
 
@@ -219,27 +219,3 @@ What this guide does not cover:
 
- Using Apache. You can investigate here:
 

	
 
  - https://groups.google.com/group/rhodecode/msg/c433074e813ffdc4
 

	
 

	
 
Upgrading
 
---------
 

	
 
Stop running Kallithea
 
Open a CommandPrompt like in Step 7 (cd to C:\Kallithea\Env\Scripts and activate) and type::
 

	
 
  pip install kallithea --upgrade
 
  cd \Kallithea\Bin
 

	
 
Backup your production.ini file now.
 

	
 
Then run::
 

	
 
  paster make-config Kallithea production.ini
 

	
 
Look for changes and update your production.ini accordingly.
 

	
 
Next, update the database::
 

	
 
  paster upgrade-db production.ini
 

	
 
More details can be found in `<upgrade.html>`_.
docs/installation_win_old.rst
Show inline comments
 
@@ -260,23 +260,3 @@ What this Guide does not cover:
 
- Using Apache. You can investigate here:
 

	
 
  - https://groups.google.com/group/rhodecode/msg/c433074e813ffdc4
 

	
 

	
 
Upgrading
 
---------
 

	
 
Stop running Kallithea
 
Open a CommandPrompt like in Step7 (VS2008 path + activate) and type::
 

	
 
 easy_install -U kallithea
 
 cd \Kallithea\Bin
 

	
 
{ backup your production.ini file now} ::
 

	
 
 paster make-config Kallithea production.ini
 

	
 
(check changes and update your production.ini accordingly) ::
 

	
 
 paster upgrade-db production.ini (update database)
 

	
 
Full steps in http://packages.python.org/Kallithea/upgrade.html
docs/upgrade.rst
Show inline comments
 
new file 100644
 
.. _upgrade:
 

	
 
===================
 
Upgrading Kallithea
 
===================
 

	
 
The following describes the upgrade steps needed, independently of the
 
Kallithea installation manner.
 

	
 

	
 
1. Stop the Kallithea web application
 
-------------------------------------
 

	
 
This step depends entirely on the web server software used to serve
 
Kallithea, but in any case, Kallithea should not be running during
 
the upgrade.
 

	
 

	
 
2. Create a backup of both database and configuration
 
-----------------------------------------------------
 

	
 
You are of course strongly recommended to make backups regularly, but it
 
is **especially** important to make a full database and configuration
 
backup before performing a Kallithea upgrade.
 

	
 

	
 
Back up your configuration
 
~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
Make a copy of your Kallithea configuration (``.ini``) file.
 

	
 

	
 
Back up your database
 
~~~~~~~~~~~~~~~~~~~~~
 

	
 
If using SQLite, simply make a copy of the Kallithea database (``.db``)
 
file.
 

	
 
If using PostgreSQL, please consult the documentation for the ``pg_dump``
 
utility.
 

	
 
If using MySQL, please consult the documentation for the ``mysqldump``
 
utility.
 

	
 
Look for ``sqlalchemy.db1.url`` in your configuration file to determine
 
database type, settings, location, etc.
 

	
 

	
 
3. Activate the Kallithea virtual environment (if any)
 
------------------------------------------------------
 

	
 
Ensure that you are using the Python environment that you originally
 
installed Kallithea in by running::
 

	
 
    pip freeze
 

	
 
This will list all packages installed in the current environment. If
 
Kallithea isn't listed, activate the correct virtual environment.
 
See the appropriate installation page for details.
 

	
 

	
 
4. Install new version of Kallithea
 
-----------------------------------
 

	
 
Please refer to the instructions for the installation method you
 
originally used to install Kallithea.
 

	
 
If you originally installed using pip, it is as simple as::
 

	
 
    pip install --upgrade kallithea
 

	
 
If you originally installed from version control, it is as simple as::
 

	
 
    cd my-kallithea-clone
 
    hg pull -u
 
    pip install -e .
 

	
 

	
 
5. Upgrade your configuration
 
-----------------------------
 

	
 
Run the following command to upgrade your configuration (``.ini``) file::
 

	
 
    paster make-config Kallithea my.ini
 

	
 
This will display any changes made by the new version of Kallithea to your
 
current configuration, and attempt an automatic merge. It is recommended
 
that you recheck the content after the merge.
 

	
 
.. note::
 
    Please always make sure your ``.ini`` files are up to date. Errors
 
    can often be caused by missing parameters added in new versions.
 

	
 

	
 
.. _dbmigrations:
 

	
 
6. Upgrade your database
 
------------------------
 

	
 
.. note::
 
    If you are *downgrading* Kallithea, you should perform the database
 
    migration step *before* installing the older version. (That is,
 
    always perform migrations using the most recent of the two versions
 
    you're migrating between.)
 

	
 
First, run the following command to see your current database version::
 

	
 
    alembic -c my.ini current
 

	
 
Typical output will be something like "9358dc3d6828 (head)", which is
 
the current Alembic database "revision ID". Write down the entire output
 
for troubleshooting purposes (in case anything goes wrong), or in case
 
you later want to revert to this Kallithea version.
 

	
 
The output will be empty if you're upgrading from Kallithea 0.3.x or
 
older. That's expected. If you get an error that the config file was not
 
found or has no ``[alembic]`` section, see the next section.
 

	
 
Next, if you are performing an *upgrade*: Run the following command to
 
upgrade your database to the current Kallithea version::
 

	
 
    alembic -c my.ini upgrade head
 

	
 
If you are performing a *downgrade*: Determine the target Alembic
 
"revision ID" (which, as noted above, you should have written down
 
before upgrading). Then run the following command to downgrade your
 
database to a given version (example shown here will downgrade to
 
Kallithea 0.4)::
 

	
 
    alembic -c my.ini downgrade 9358dc3d6828
 

	
 
Alembic will show the necessary migrations (if any) as it executes
 
them. If no "ERROR" is displayed, the command was successful.
 

	
 
Should an error occur, the database may be "stranded" half-way
 
through the migration, and you should restore it from backup.
 

	
 

	
 
Enabling old Kallithea config files for Alembic use
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
Kallithea configuration files created before the introduction of Alembic
 
(i.e. predating Kallithea 0.4) needs to be updated for use with Alembic.
 
Without this, Alembic will fail with an error along the following lines::
 

	
 
    FAILED: No config file 'my.ini' found, or file has no '[alembic]' section
 

	
 
If Alembic complains specifically about a missing ``alembic.ini``, it is
 
likely because you did not specify a config file using the ``-c`` option.
 
On the other hand, if the mentioned config file actually exists, you
 
need to append the following lines to it::
 

	
 
    [alembic]
 
    script_location = kallithea:alembic
 

	
 
    [logger_alembic]
 
    level = INFO
 
    handlers =
 
    qualname = alembic
 

	
 
Next, find the existing ``loggers.keys`` entry in the file and append the
 
item ``alembic`` to it, like this::
 

	
 
    [loggers]
 
    keys = root, routes, kallithea, sqlalchemy, beaker, templates, whoosh_indexer, alembic
 

	
 
Your config file should now work with Alembic.
 

	
 

	
 
7. Rebuild the Whoosh full-text index
 
-------------------------------------
 

	
 
It is recommended that you rebuild the Whoosh index after upgrading since
 
new Whoosh versions can introduce incompatible index changes.
 

	
 

	
 
8. Start the Kallithea web application
 
--------------------------------------
 

	
 
This step once again depends entirely on the web server software used to
 
serve Kallithea.
 

	
 
Before starting the new version of Kallithea, you may find it helpful to
 
clear out your log file so that new errors are readily apparent.
 

	
 
.. note::
 
    If you're using Celery, make sure you restart all instances of it after
 
    upgrade.
 

	
 

	
 
.. _virtualenv: http://pypi.python.org/pypi/virtualenv
kallithea/__init__.py
Show inline comments
 
@@ -44,28 +44,15 @@ CONFIG = {}
 
# Linked module for extensions
 
EXTENSIONS = {}
 

	
 
# BRAND controls internal references in database and config to the products
 
# own name.
 
#
 
# NOTE: If you want compatibility with a database that was originally created
 
#  for use with the RhodeCode software product, change BRAND to "rhodecode",
 
#  either by editing here or by creating a new file:
 
#  echo "BRAND = 'rhodecode'" > kallithea/brand.py
 

	
 
BRAND = "kallithea"
 
try:
 
    from kallithea.brand import BRAND
 
    import kallithea.brand
 
except ImportError:
 
    pass
 

	
 
# Prefix for the ui and settings table names
 
DB_PREFIX = (BRAND + "_") if BRAND != "kallithea" else ""
 
else:
 
    assert False, 'Database rebranding is no longer supported; see README.'
 

	
 
# Users.extern_type and .extern_name value for local users
 
EXTERN_TYPE_INTERNAL = BRAND if BRAND != 'kallithea' else 'internal'
 

	
 
# db_migrate_version.repository_id value, same as kallithea/lib/dbmigrate/migrate.cfg
 
DB_MIGRATIONS = BRAND + "_db_migrations"
 
EXTERN_TYPE_INTERNAL = 'internal'
 

	
 
try:
 
    from kallithea.lib import get_current_revision
kallithea/alembic/env.py
Show inline comments
 
new file 100644
 
# Alembic environment (configuration), based on file generated using
 
# "alembic init" and modified for Kallithea.
 
#
 
# Portions copyright (C) 2009-2016 by Michael Bayer.
 

	
 
from logging.config import fileConfig
 

	
 
from alembic import context
 
from sqlalchemy import engine_from_config, pool
 

	
 

	
 
# this is the Alembic Config object, which provides
 
# access to the values within the .ini file in use.
 
config = context.config
 

	
 
# Setup Python loggers based on the config file provided to the alembic
 
# command. If we're being invoked via the Alembic API (presumably for
 
# stamping during "paster setup-db"), config_file_name is not available,
 
# and loggers are presumed to already have been configured.
 
if config.config_file_name:
 
    fileConfig(config.config_file_name)
 

	
 
# Support autogeneration of migration scripts based on "diff" between
 
# current database schema and kallithea.model.db schema.
 
from kallithea.model import db
 
target_metadata = db.Base.metadata
 

	
 
# other values from the config, defined by the needs of env.py,
 
# can be acquired:
 
# my_important_option = config.get_main_option("my_important_option")
 
# ... etc.
 

	
 

	
 
def run_migrations_offline():
 
    """Run migrations in 'offline' mode.
 

	
 
    This configures the context with just a URL
 
    and not an Engine, though an Engine is acceptable
 
    here as well.  By skipping the Engine creation
 
    we don't even need a DBAPI to be available.
 

	
 
    Calls to context.execute() here emit the given string to the
 
    script output.
 

	
 
    """
 
    # Default to use the main Kallithea database string in [app:main].
 
    # For advanced uses, this can be overriden by specifying an explicit
 
    # [alembic] sqlalchemy.url.
 
    url = (
 
        config.get_main_option('sqlalchemy.url') or
 
        config.get_section_option('app:main', 'sqlalchemy.db1.url')
 
    )
 
    context.configure(
 
        url=url, target_metadata=target_metadata, literal_binds=True)
 

	
 
    with context.begin_transaction():
 
        context.run_migrations()
 

	
 

	
 
def run_migrations_online():
 
    """Run migrations in 'online' mode.
 

	
 
    In this scenario we need to create an Engine
 
    and associate a connection with the context.
 

	
 
    """
 
    cfg = config.get_section(config.config_ini_section)
 
    # Default to use the main Kallithea database string in [app:main].
 
    # For advanced uses, this can be overriden by specifying an explicit
 
    # [alembic] sqlalchemy.url.
 
    if 'sqlalchemy.url' not in cfg:
 
        cfg['sqlalchemy.url'] = config.get_section_option('app:main', 'sqlalchemy.db1.url')
 
    connectable = engine_from_config(
 
        cfg,
 
        prefix='sqlalchemy.',
 
        poolclass=pool.NullPool)
 

	
 
    with connectable.connect() as connection:
 
        context.configure(
 
            connection=connection,
 
            target_metadata=target_metadata
 
        )
 

	
 
        with context.begin_transaction():
 
            context.run_migrations()
 

	
 

	
 
if context.is_offline_mode():
 
    run_migrations_offline()
 
else:
 
    run_migrations_online()
kallithea/alembic/script.py.mako
Show inline comments
 
new file 100644
 
## Template for creating new Alembic migration scripts, based on file
 
## generated using "alembic init" and modified for Kallithea.
 
##
 
## Portions copyright (C) 2009-2016 by Michael Bayer.
 
"""${message}
 

	
 
Revision ID: ${up_revision}
 
Revises: ${down_revision | comma,n}
 
Create Date: ${create_date}
 

	
 
"""
 

	
 
# The following opaque hexadecimal identifiers ("revisions") are used
 
# by Alembic to track this migration script and its relations to others.
 
revision = ${repr(up_revision)}
 
down_revision = ${repr(down_revision)}
 
branch_labels = ${repr(branch_labels)}
 
depends_on = ${repr(depends_on)}
 

	
 
from alembic import op
 
import sqlalchemy as sa
 
${imports if imports else ""}
 

	
 
def upgrade():
 
    ${upgrades if upgrades else "pass"}
 

	
 

	
 
def downgrade():
 
    ${downgrades if downgrades else "pass"}
kallithea/alembic/versions/9358dc3d6828_drop_sqlalchemy_migrate_support.py
Show inline comments
 
new file 100644
 
"""Drop SQLAlchemy Migrate support
 

	
 
Revision ID: 9358dc3d6828
 
Revises:
 
Create Date: 2016-03-01 15:21:30.896585
 

	
 
"""
 

	
 
# The following opaque hexadecimal identifiers ("revisions") are used
 
# by Alembic to track this migration script and its relations to others.
 
revision = '9358dc3d6828'
 
down_revision = None
 
branch_labels = None
 
depends_on = None
 

	
 
from alembic import op
 
import sqlalchemy as sa
 

	
 

	
 
def upgrade():
 
    op.drop_table('db_migrate_version')
 

	
 

	
 
def downgrade():
 
    raise NotImplementedError('cannot revert to SQLAlchemy Migrate')
kallithea/bin/rebranddb.py
Show inline comments
 
deleted file
kallithea/bin/template.ini.mako
Show inline comments
 
@@ -505,11 +505,18 @@ sqlalchemy.db1.echo = false
 
sqlalchemy.db1.pool_recycle = 3600
 

	
 
<%text>################################</%text>
 
<%text>### ALEMBIC CONFIGURATION   ####</%text>
 
<%text>################################</%text>
 

	
 
[alembic]
 
script_location = kallithea:alembic
 

	
 
<%text>################################</%text>
 
<%text>### LOGGING CONFIGURATION   ####</%text>
 
<%text>################################</%text>
 

	
 
[loggers]
 
keys = root, routes, kallithea, sqlalchemy, beaker, templates, whoosh_indexer
 
keys = root, routes, kallithea, sqlalchemy, alembic, beaker, templates, whoosh_indexer
 

	
 
[handlers]
 
keys = console, console_sql
 
@@ -556,6 +563,11 @@ handlers = console_sql
 
qualname = sqlalchemy.engine
 
propagate = 0
 

	
 
[logger_alembic]
 
level = INFO
 
handlers =
 
qualname = alembic
 

	
 
[logger_whoosh_indexer]
 
level = DEBUG
 
handlers =
kallithea/config/deployment.ini_tmpl
Show inline comments
 
@@ -494,11 +494,18 @@ sqlalchemy.db1.echo = false
 
sqlalchemy.db1.pool_recycle = 3600
 

	
 
################################
 
### ALEMBIC CONFIGURATION   ####
 
################################
 

	
 
[alembic]
 
script_location = kallithea:alembic
 

	
 
################################
 
### LOGGING CONFIGURATION   ####
 
################################
 

	
 
[loggers]
 
keys = root, routes, kallithea, sqlalchemy, beaker, templates, whoosh_indexer
 
keys = root, routes, kallithea, sqlalchemy, alembic, beaker, templates, whoosh_indexer
 

	
 
[handlers]
 
keys = console, console_sql
 
@@ -545,6 +552,11 @@ handlers = console_sql
 
qualname = sqlalchemy.engine
 
propagate = 0
 

	
 
[logger_alembic]
 
level = INFO
 
handlers =
 
qualname = alembic
 

	
 
[logger_whoosh_indexer]
 
level = DEBUG
 
handlers =
kallithea/lib/db_manage.py
Show inline comments
 
@@ -33,12 +33,15 @@ import uuid
 
import logging
 
from os.path import dirname as dn, join as jn
 

	
 
from kallithea import __dbversion__, __py_version__, EXTERN_TYPE_INTERNAL, DB_MIGRATIONS
 
import alembic.config
 
import alembic.command
 

	
 
from kallithea import __dbversion__, __py_version__, EXTERN_TYPE_INTERNAL
 
from kallithea.model.user import UserModel
 
from kallithea.lib.utils import ask_ok
 
from kallithea.model import init_model
 
from kallithea.model.db import User, Permission, Ui, \
 
    Setting, UserToPerm, DbMigrateVersion, RepoGroup, \
 
    Setting, UserToPerm, RepoGroup, \
 
    UserRepoGroupToPerm, CacheInvalidation, Repository
 

	
 
from sqlalchemy.engine import create_engine
 
@@ -103,81 +106,19 @@ class DbManage(object):
 

	
 
        checkfirst = not override
 
        Base.metadata.create_all(checkfirst=checkfirst)
 
        log.info('Created tables for %s', self.dbname)
 

	
 
    def set_db_version(self):
 
        ver = DbMigrateVersion()
 
        ver.version = __dbversion__
 
        ver.repository_id = DB_MIGRATIONS
 
        ver.repository_path = 'versions'
 
        self.sa.add(ver)
 
        log.info('db version set to: %s', __dbversion__)
 

	
 
    def upgrade(self):
 
        """
 
        Upgrades given database schema to given revision following
 
        all needed steps, to perform the upgrade
 

	
 
        """
 

	
 
        from kallithea.lib.dbmigrate.migrate.versioning import api
 
        from kallithea.lib.dbmigrate.migrate.exceptions import \
 
            DatabaseNotControlledError
 

	
 
        if 'sqlite' in self.dburi:
 
            print (
 
               '********************** WARNING **********************\n'
 
               'Make sure your version of sqlite is at least 3.7.X.  \n'
 
               'Earlier versions are known to fail on some migrations\n'
 
               '*****************************************************\n')
 

	
 
        upgrade = ask_ok('You are about to perform database upgrade, make '
 
                         'sure You backed up your database before. '
 
                         'Continue ? [y/n]')
 
        if not upgrade:
 
            print 'No upgrade performed'
 
            sys.exit(0)
 

	
 
        repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))),
 
                             'kallithea/lib/dbmigrate')
 
        db_uri = self.dburi
 

	
 
        try:
 
            curr_version = api.db_version(db_uri, repository_path)
 
            msg = ('Found current database under version '
 
                   'control with version %s' % curr_version)
 

	
 
        except (RuntimeError, DatabaseNotControlledError):
 
            curr_version = 1
 
            msg = ('Current database is not under version control. Setting '
 
                   'as version %s' % curr_version)
 
            api.version_control(db_uri, repository_path, curr_version)
 

	
 
        notify(msg)
 
        if curr_version == __dbversion__:
 
            print 'This database is already at the newest version'
 
            sys.exit(0)
 
        # Create an Alembic configuration and generate the version table,
 
        # "stamping" it with the most recent Alembic migration revision, to
 
        # tell Alembic that all the schema upgrades are already in effect.
 
        alembic_cfg = alembic.config.Config()
 
        alembic_cfg.set_main_option('script_location', 'kallithea:alembic')
 
        alembic_cfg.set_main_option('sqlalchemy.url', self.dburi)
 
        # This command will give an error in an Alembic multi-head scenario,
 
        # but in practice, such a scenario should not come up during database
 
        # creation, even during development.
 
        alembic.command.stamp(alembic_cfg, 'head')
 

	
 
        # clear cache keys
 
        log.info("Clearing cache keys now...")
 
        CacheInvalidation.clear_cache()
 

	
 
        upgrade_steps = range(curr_version + 1, __dbversion__ + 1)
 
        notify('attempting to do database upgrade from '
 
               'version %s to version %s' % (curr_version, __dbversion__))
 

	
 
        # CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
 
        _step = None
 
        for step in upgrade_steps:
 
            notify('performing upgrade step %s' % step)
 
            time.sleep(0.5)
 

	
 
            api.upgrade(db_uri, repository_path, step)
 
            notify('schema upgrade for step %s completed' % (step,))
 

	
 
            _step = step
 

	
 
        notify('upgrade to version %s successful' % _step)
 
        log.info('Created tables for %s', self.dbname)
 

	
 
    def fix_repo_paths(self):
 
        """
kallithea/lib/dbmigrate.py
Show inline comments
 
new file 100644
 
from paste.script.command import Command
 

	
 
class UpgradeDb(Command):
 
    hidden = True
 

	
 
    def run(self, args):
 
        raise SystemExit(
 
            'The "paster upgrade-db" command has been removed; please see the docs:\n'
 
            '    https://kallithea.readthedocs.io/en/latest/upgrade.html'
 
        )
kallithea/lib/dbmigrate/__init__.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate.cfg
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/__init__.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/changeset/__init__.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/changeset/ansisql.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/changeset/constraint.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/changeset/databases/__init__.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/changeset/databases/firebird.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/changeset/databases/mysql.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/changeset/databases/oracle.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/changeset/databases/postgres.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/changeset/databases/sqlite.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/changeset/databases/visitor.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/changeset/schema.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/exceptions.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/__init__.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/api.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/cfgparse.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/config.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/genmodel.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/migrate_repository.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/pathed.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/repository.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/schema.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/schemadiff.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/script/__init__.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/script/base.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/script/py.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/script/sql.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/shell.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/template.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/__init__.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/manage.py_tmpl
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/manage/default.py_tmpl
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/manage/pylons.py_tmpl
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/repository/__init__.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/repository/default/README
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/repository/default/__init__.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/repository/default/migrate.cfg
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/repository/default/versions/__init__.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/repository/pylons/README
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/repository/pylons/__init__.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/repository/pylons/migrate.cfg
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/repository/pylons/versions/__init__.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/script/__init__.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/script/default.py_tmpl
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/script/pylons.py_tmpl
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/sql_script/default.py_tmpl
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/templates/sql_script/pylons.py_tmpl
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/util/__init__.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/util/importpath.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/util/keyedinstance.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/migrate/versioning/version.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/schema/__init__.py
Show inline comments
 
deleted file
kallithea/lib/dbmigrate/schema/db_1_1_0.py
Show inline comments
 
deleted file

Changeset was too big and was cut off... Show full diff anyway

5 comments (0 inline, 5 general) First comment
Søren Løvborg (kwi) 8 years and 10 months ago comment on pull request "Move to Alembic for database migrations (v2)"

Status change: Under review

Dominik Ruf (domruf) 8 years and 9 months ago comment on pull request "Move to Alembic for database migrations (v2)"
Dominik Ruf (domruf) 8 years and 9 months ago comment on pull request "Move to Alembic for database migrations (v2)"
@kiilerix is there anything I can do to push this forward?
Mads Kiilerich (kiilerix) 8 years and 9 months ago comment on pull request "Move to Alembic for database migrations (v2)"
I hope @kwi soon will post an updated PR that either needs testing and review, or perhaps also has some TODO items you can help with.
You need to be logged in to comment. Login now