# HG changeset patch # User Mads Kiilerich # Date 2020-06-24 23:51:18 # Node ID 307c876a6e89671f65ca5203c125b563ccc601c4 # Parent 8759238d73562f0ce73d4cd5dc428873926ea294 db: introduce db-create --reuse option Support use of an existing database so the Kallithea database user doesn't have to be granted permissions to create databases. The existing database must of course have been created "correctly", for example using the right charset and collation on MariaDB/MySQL. Creating the database manually also provides a way to avoid the hardcoded defaults. diff --git a/docs/setup.rst b/docs/setup.rst --- a/docs/setup.rst +++ b/docs/setup.rst @@ -84,6 +84,15 @@ repositories Kallithea will add all of t location to its database. (Note: make sure you specify the correct path to the root). +.. note:: It is also possible to use an existing database. For example, + when using PostgreSQL without granting general createdb privileges to + the PostgreSQL kallithea user, set ``sqlalchemy.url = + postgresql://kallithea:password@localhost/kallithea`` and create the + database like:: + + sudo -u postgres createdb 'kallithea' --owner 'kallithea' + kallithea-cli db-create -c my.ini --reuse + Prepare front-end files ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/kallithea/bin/kallithea_cli_db.py b/kallithea/bin/kallithea_cli_db.py --- a/kallithea/bin/kallithea_cli_db.py +++ b/kallithea/bin/kallithea_cli_db.py @@ -20,6 +20,8 @@ from kallithea.model.meta import Session @cli_base.register_command(config_file=True) +@click.option('--reuse/--no-reuse', default=False, + help='Reuse and clean existing database instead of dropping and creating (default: no reuse)') @click.option('--user', help='Username of administrator account.') @click.option('--password', help='Password for administrator account.') @click.option('--email', help='Email address of administrator account.') @@ -28,7 +30,7 @@ from kallithea.model.meta import Session @click.option('--force-no', is_flag=True, help='Answer no to every question.') @click.option('--public-access/--no-public-access', default=True, help='Enable/disable public access on this installation (default: enable)') -def db_create(user, password, email, repos, force_yes, force_no, public_access): +def db_create(user, password, email, repos, force_yes, force_no, public_access, reuse): """Initialize the database. Create all required tables in the database specified in the configuration @@ -57,7 +59,7 @@ def db_create(user, password, email, rep ) dbmanage = DbManage(dbconf=dbconf, root=kallithea.CONFIG['here'], tests=False, cli_args=cli_args) - dbmanage.create_tables() + dbmanage.create_tables(reuse_database=reuse) repo_root_path = dbmanage.prompt_repo_root_path(None) dbmanage.create_settings(repo_root_path) dbmanage.create_default_user() diff --git a/kallithea/lib/db_manage.py b/kallithea/lib/db_manage.py --- a/kallithea/lib/db_manage.py +++ b/kallithea/lib/db_manage.py @@ -72,20 +72,28 @@ class DbManage(object): init_model(engine) self.sa = Session() - def create_tables(self): + def create_tables(self, reuse_database=False): """ Create database (optional) and tables. - The database will be dropped (if it exists) and a new one created. + If reuse_database is false, the database will be dropped (if it exists) + and a new one created. If true, the existing database will be reused + and cleaned for content. """ url = sqlalchemy.engine.url.make_url(self.dburi) database = url.database - log.info("The existing database %r will be destroyed and created." % database) + if reuse_database: + log.info("The content of the database %r will be destroyed and new tables created." % database) + else: + log.info("The existing database %r will be destroyed and a new one created." % database) + if not self.tests: if not self._ask_ok('Are you sure to destroy old database? [y/n]'): print('Nothing done.') sys.exit(0) - if True: + if reuse_database: + Base.metadata.drop_all() + else: if url.drivername == 'mysql': url.database = None # don't connect to the database (it might not exist) engine = sqlalchemy.create_engine(url)