From 91c62408fc31ecc6fc1f0179f6d307e7d14819cd Mon Sep 17 00:00:00 2001 From: Maxim Tacu Date: Wed, 13 Jan 2021 12:44:45 +0000 Subject: [PATCH 1/8] Updated dependencies --- setup.py | 18 ++++++++-------- stellar/app.py | 10 ++++----- stellar/command.py | 51 +++++++++++++++------------------------------- stellar/config.py | 6 ++---- 4 files changed, 32 insertions(+), 53 deletions(-) diff --git a/setup.py b/setup.py index 31a1ac2..2b5e93d 100644 --- a/setup.py +++ b/setup.py @@ -5,8 +5,6 @@ from setuptools import setup, find_packages -# https://bitbucket.org/zzzeek/alembic/raw/f38eaad4a80d7e3d893c3044162971971ae0 -# 09bf/setup.py with open( os.path.join(os.path.dirname(__file__), 'stellar', 'app.py') ) as app_file: @@ -48,12 +46,14 @@ 'Topic :: Software Development :: Version Control', ], install_requires = [ - 'PyYAML>=3.11', - 'SQLAlchemy>=0.9.6', - 'humanize>=0.5.1', - 'schema>=0.3.1', - 'click>=3.1', - 'SQLAlchemy-Utils>=0.26.11', - 'psutil>=2.1.1', + 'PyYAML>=5.3.1', + 'SQLAlchemy>=1.3.22', + 'humanize>=3.2.0', + 'schema>=0.7.2', + 'click>=7.1.2', + 'SQLAlchemy-Utils>=0.36.8', + 'psutil>=5.8.0', + 'wheel>=0.36.2', + 'psycopg2-binary>=2.8.6' ] ) diff --git a/stellar/app.py b/stellar/app.py index 97406b2..35c832f 100644 --- a/stellar/app.py +++ b/stellar/app.py @@ -21,7 +21,7 @@ from psutil import pid_exists -__version__ = '0.4.5' +__version__ = '0.5.0' logger = logging.getLogger(__name__) @@ -49,7 +49,7 @@ def load_config(self): logging.basicConfig(level=self.config['logging']) def init_database(self): - self.raw_db = create_engine(self.config['url'], echo=False) + self.raw_db = create_engine(self.config['url']) self.raw_conn = self.raw_db.connect() self.operations = Operations(self.raw_conn, self.config) @@ -58,11 +58,11 @@ def init_database(self): except AttributeError: logger.info('Could not set isolation level to 0') - self.db = create_engine(self.config['stellar_url'], echo=False) + self.db = create_engine(self.config['stellar_url']) self.db.session = sessionmaker(bind=self.db)() self.raw_db.session = sessionmaker(bind=self.raw_db)() - tables_missing = self.create_stellar_database() - + + self.create_stellar_database() self.create_stellar_tables() # logger.getLogger('sqlalchemy.engine').setLevel(logger.WARN) diff --git a/stellar/command.py b/stellar/command.py index b6764d9..0f5790b 100644 --- a/stellar/command.py +++ b/stellar/command.py @@ -13,20 +13,8 @@ from .operations import database_exists, list_of_databases, SUPPORTED_DIALECTS -def upgrade_from_old_version(app): - if app.config['migrate_from_0_3_2']: - if app.is_old_database(): - click.echo('Upgrading from old Stellar version...') - def after_rename(old_name, new_name): - click.echo('* Renamed %s to %s' % (old_name, new_name)) - app.update_database_names_to_new_version(after_rename=after_rename) - - app.config['migrate_from_0_3_2'] = False - save_config(app.config) - def get_app(): app = Stellar() - upgrade_from_old_version(app) return app @@ -49,7 +37,6 @@ def after_delete(database): click.echo("Deleted table %s" % database) app = get_app() - upgrade_from_old_version(app) app.delete_orphan_snapshots(after_delete) @@ -58,7 +45,6 @@ def after_delete(database): def snapshot(name): """Takes a snapshot of the database""" app = get_app() - upgrade_from_old_version(app) name = name or app.default_snapshot_name if app.get_snapshot(name): @@ -195,14 +181,15 @@ def init(): if url.count('/') == 2 and not url.endswith('/'): url = url + '/' - if ( - url.count('/') == 3 and - url.endswith('/') and - url.startswith('postgresql://') - ): - connection_url = url + 'template1' - else: - connection_url = url + # if ( + # url.count('/') == 3 and + # url.endswith('/') and + # url.startswith('postgresql://') + # ): + # connection_url = url + 'template1' + # else: + # connection_url = url + connection_url = url engine = create_engine(connection_url, echo=False) try: @@ -249,22 +236,16 @@ def init(): raw_url = url if engine.dialect.name == 'postgresql': - raw_url = raw_url + 'template1' + raw_url = raw_url + db_name with open('stellar.yaml', 'w') as project_file: project_file.write( + f""" +project_name: {name} +tracked_databases: ['{db_name}'] +url: '{raw_url}' +stellar_url: '{url}stellar_data' """ -project_name: '%(name)s' -tracked_databases: ['%(db_name)s'] -url: '%(raw_url)s' -stellar_url: '%(url)sstellar_data' - """.strip() % - { - 'name': name, - 'raw_url': raw_url, - 'url': url, - 'db_name': db_name - } ) click.echo("Wrote stellar.yaml") @@ -286,7 +267,7 @@ def main(): sys.exit(1) except ImportError as e: libraries = { - 'psycopg2': 'PostreSQL', + 'psycopg2': 'PostgreSQL', 'pymysql': 'MySQL', } for library, name in libraries.items(): diff --git a/stellar/config.py b/stellar/config.py index 98a358d..271a717 100644 --- a/stellar/config.py +++ b/stellar/config.py @@ -13,16 +13,14 @@ class MissingConfig(Exception): default_config = { - 'logging': 30, - 'migrate_from_0_3_2': True + 'logging': 30 } schema = Schema({ 'stellar_url': Use(str), 'url': Use(str), 'project_name': Use(str), 'tracked_databases': [Use(str)], - Optional('logging'): int, - Optional('migrate_from_0_3_2'): bool + Optional('logging'): int }) From d63e35516bd21dac9fa49fb13ae9e5c8042f450b Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Tue, 12 Oct 2021 03:20:56 +0300 Subject: [PATCH 2/8] Keep `humanize` compatibility with Python 3.5 Because old docker images use it. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 2b5e93d..1190542 100644 --- a/setup.py +++ b/setup.py @@ -48,7 +48,7 @@ install_requires = [ 'PyYAML>=5.3.1', 'SQLAlchemy>=1.3.22', - 'humanize>=3.2.0', + 'humanize>=2.6.0', 'schema>=0.7.2', 'click>=7.1.2', 'SQLAlchemy-Utils>=0.36.8', From 0c4a1fbc64389933672e230a801dfabef4b559cc Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Tue, 12 Oct 2021 03:33:06 +0300 Subject: [PATCH 3/8] Keep it Python 3.5 compatible for a while --- stellar/command.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/stellar/command.py b/stellar/command.py index 0f5790b..aefd0a5 100644 --- a/stellar/command.py +++ b/stellar/command.py @@ -240,13 +240,12 @@ def init(): with open('stellar.yaml', 'w') as project_file: project_file.write( - f""" + """ project_name: {name} tracked_databases: ['{db_name}'] url: '{raw_url}' stellar_url: '{url}stellar_data' - """ - ) + """.format(name=name, db_name=db_name, raw_url=raw_url, url=url)) click.echo("Wrote stellar.yaml") click.echo('') From e950d34bd8060b5dd2a2c04421c0cd1693c44844 Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Tue, 12 Oct 2021 04:25:12 +0300 Subject: [PATCH 4/8] Add optional URL argument to `stellar init` --- stellar/command.py | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/stellar/command.py b/stellar/command.py index aefd0a5..c9d97e4 100644 --- a/stellar/command.py +++ b/stellar/command.py @@ -1,3 +1,4 @@ +import textwrap import sys from datetime import datetime from time import sleep @@ -6,7 +7,7 @@ import click import logging from sqlalchemy import create_engine -from sqlalchemy.exc import OperationalError +from sqlalchemy.exc import ArgumentError, OperationalError from .app import Stellar, __version__ from .config import InvalidConfig, MissingConfig, load_config, save_config @@ -169,15 +170,24 @@ def replace(name): @stellar.command() -def init(): +@click.argument('url', required=False) +def init(url): """Initializes Stellar configuration.""" + + def prompt_url(): + msg = textwrap.dedent("""\ + Please enter the url for your database. + + For example: + PostgreSQL: postgresql://localhost:5432/ + MySQL: mysql+pymysql://root@localhost/ + """) + return click.prompt(msg) + while True: - url = click.prompt( - "Please enter the url for your database.\n\n" - "For example:\n" - "PostgreSQL: postgresql://localhost:5432/\n" - "MySQL: mysql+pymysql://root@localhost/" - ) + if not url: + url = prompt_url() + if url.count('/') == 2 and not url.endswith('/'): url = url + '/' @@ -191,16 +201,24 @@ def init(): # connection_url = url connection_url = url - engine = create_engine(connection_url, echo=False) + try: + engine = create_engine(connection_url, echo=False) + except ArgumentError as err: + click.echo("Error: %s" % err) + url = None + continue + try: conn = engine.connect() except OperationalError as err: click.echo("Could not connect to database: %s" % url) - click.echo("Error message: %s" % err.message) + click.echo("Error message: %s" % err) click.echo('') else: break + url = None + if engine.dialect.name not in SUPPORTED_DIALECTS: click.echo("Your engine dialect %s is not supported." % ( engine.dialect.name From 799fdcbfeeb60f319c55375af8be5c1bacb230ce Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Tue, 12 Oct 2021 11:11:38 +0300 Subject: [PATCH 5/8] Use `textwrap` to format config --- stellar/command.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/stellar/command.py b/stellar/command.py index c9d97e4..34fccb2 100644 --- a/stellar/command.py +++ b/stellar/command.py @@ -258,12 +258,13 @@ def prompt_url(): with open('stellar.yaml', 'w') as project_file: project_file.write( - """ -project_name: {name} -tracked_databases: ['{db_name}'] -url: '{raw_url}' -stellar_url: '{url}stellar_data' - """.format(name=name, db_name=db_name, raw_url=raw_url, url=url)) + textwrap.dedent("""\ + project_name: {name} + tracked_databases: ['{db_name}'] + url: '{raw_url}' + stellar_url: '{url}stellar_data' + """) + .format(name=name, db_name=db_name, raw_url=raw_url, url=url)) click.echo("Wrote stellar.yaml") click.echo('') From c89e26ee707ba32e9969ed5ed972990fe5f44d90 Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Tue, 12 Oct 2021 11:40:57 +0300 Subject: [PATCH 6/8] Add shorthand -h option for click https://github.com/pallets/click/issues/1433#issuecomment-590113228 --- stellar/command.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stellar/command.py b/stellar/command.py index 34fccb2..81d7fb6 100644 --- a/stellar/command.py +++ b/stellar/command.py @@ -19,7 +19,7 @@ def get_app(): return app -@click.group() +@click.group(context_settings={"help_option_names": ["-h", "--help"]}) def stellar(): """Fast database snapshots for development. It's like Git for databases.""" pass From 4c49f9038972661acc4c62396bd67528183382bf Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Tue, 12 Oct 2021 11:54:46 +0300 Subject: [PATCH 7/8] Add project argument to `stellar init` for automation $ stellar init -h Usage: stellar init [OPTIONS] [URL] [PROJECT] --- stellar/command.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/stellar/command.py b/stellar/command.py index 81d7fb6..5e4d4cb 100644 --- a/stellar/command.py +++ b/stellar/command.py @@ -171,7 +171,8 @@ def replace(name): @stellar.command() @click.argument('url', required=False) -def init(url): +@click.argument('project', required=False) +def init(url, project): """Initializes Stellar configuration.""" def prompt_url(): @@ -246,10 +247,11 @@ def prompt_url(): db_name = url.rsplit('/', 1)[-1] url = url.rsplit('/', 1)[0] + '/' - name = click.prompt( - 'Please enter your project name (used internally, eg. %s)' % db_name, - default=db_name - ) + if project is None: + project = click.prompt( + 'Please enter project name (used internally, eg. %s)' % db_name, + default=db_name + ) raw_url = url @@ -264,7 +266,7 @@ def prompt_url(): url: '{raw_url}' stellar_url: '{url}stellar_data' """) - .format(name=name, db_name=db_name, raw_url=raw_url, url=url)) + .format(name=project, db_name=db_name, raw_url=raw_url, url=url)) click.echo("Wrote stellar.yaml") click.echo('') From fa086eddf3c10f7d60c6a08f2b964145582cbe84 Mon Sep 17 00:00:00 2001 From: Maxim Tacu Date: Thu, 11 Nov 2021 09:38:46 +0000 Subject: [PATCH 8/8] Updated vversions in requirements.txt --- requirements.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/requirements.txt b/requirements.txt index b9c1bcc..86b5c69 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ -PyYAML>=3.11 -SQLAlchemy>=0.9.6 -humanize>=0.5.1 -schema>=0.3.1 -psutil>=2.1.1 -click>=3.1 -SQLAlchemy-Utils>=0.26.11 +PyYAML>=5.3.1 +SQLAlchemy>=1.3.22 +humanize>=2.6.0 +schema>=0.7.2 +psutil>=5.8.0 +click>=7.1.2 +SQLAlchemy-Utils>=0.36.8