0

I have this code for a function to populate a connection string for sqlalchemy

def sql_path(yaml_path=None, login_key='login', user_key='username',
             pass_key='password', api_key=None, dialect=None,
             driver=None, host='localhost', port=None, database=None):
    
    with open(yaml_path, 'r') as file:
        sql_yaml = yaml.load(file, Loader=yaml.FullLoader)
    user = sql_yaml[login_key][user_key]
    password = sql_yaml[login_key][pass_key]
    pw_encoded = urllib.parse.quote_plus(password)
    if api_key is not None:
        if 'dialect' in sql_yaml[api_key].keys():
            dialect = sql_yaml[api_key]['dialect']
        if 'driver' in sql_yaml[api_key].keys():
            driver = sql_yaml[api_key]['driver']
        if 'host' in sql_yaml[api_key].keys():
            host = sql_yaml[api_key]['host']
        if 'port' in sql_yaml[api_key].keys():
            port = sql_yaml[api_key]['port']
        if 'database' in sql_yaml[api_key].keys():
            database = sql_yaml[api_key]['database']

    if port is None:
        sql_path = f'{dialect}+{driver}://{user}:{pw_encoded}@{host}/{database}'
    else:
        sql_path = f'{dialect}+{driver}://{user}:{pw_encoded}@{host}:{port}/{database}'
    
    return sql_path

Is there a way to dynamically assign the variables in the 'if api_key...' block without having to do an if statement for each of them?

7
  • 1
    Why use separate variables at all? Commented Dec 21, 2020 at 23:41
  • 1
    For example, if you use v = sql_yaml[api_key], you can have sql_path = f'{v["dialect"]}+{v["driver"]}://{v["user"]}:... Commented Dec 21, 2020 at 23:42
  • Also, instead of using the if statements at all, just use get. Commented Dec 21, 2020 at 23:42
  • 1
    That would make it, for example, dialect = sql_yaml[api_key].get('dialect', dialect), with no if needed, if you do want to continue using separate variables. Commented Dec 21, 2020 at 23:43
  • Granted, it is possible to update your locals by merging a dict into them; I just don't see a compelling need for it -- it makes static checking tools unable to handle your code, so it's something that should only be done when you have a much more compelling reason than just a little bit of terseness. Commented Dec 21, 2020 at 23:44

1 Answer 1

1

Use get which will default to None if the key is not found

Replace

if api_key is not None:
    if 'dialect' in sql_yaml[api_key].keys():
        dialect = sql_yaml[api_key]['dialect']
    if 'driver' in sql_yaml[api_key].keys():
        driver = sql_yaml[api_key]['driver']
    if 'host' in sql_yaml[api_key].keys():
        host = sql_yaml[api_key]['host']
    if 'port' in sql_yaml[api_key].keys():
        port = sql_yaml[api_key]['port']
    if 'database' in sql_yaml[api_key].keys():
        database = sql_yaml[api_key]['database']

with

if api_key:
    dialect = sql_yaml[api_key].get('dialect')
    driver = sql_yaml[api_key].get('driver')
    host = sql_yaml[api_key].get('host')
    port = sql_yaml[api_key].get('port')
    database = sql_yaml[api_key].get('database')

OR with

if api_key:
    dialect,  driver,  host,  port,  database = map(sql_yaml[api_key].get, ['dialect', 'driver', 'host', 'port', 'database'])
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the post. I went with your suggestion and added the second value, so it could be assigned by keyword if it doesn't appear in the yaml file.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.