<commit_before>SQLAlchemy Loading Tools
========================

A collection of wrappers and functions to make SQLAlchemy core easier 
to use in an ETL application. The package is used only for database
abstraction and not as an ORM, allowing users to write extraction
scripts that can work with multiple database backends. Functions
include:

* **Self-expanding schema**. If a column is written that does not
  exist on the table, it will be created automatically.
* **Upserts**. Records are either created or updated, depdending on
  whether an existing version can be found.
* **Query helpers** for simple queries such as all rows in a table or
  all distinct values of a set of columns.


Example
-------

A typical use case for ``sqlaload`` may include code like this::

  from sqlaload import connect, get_table, distinct, update

  engine = connect('sqlite:///customers.db')
  table = get_table('customers')
  for entry in distinct(engine, table, 'post_code', 'city')
      lon, lat = geocode(entry['post_code'], entry['city'])
      update(entry, {'lon': lon, 'lat': lat})

In this example, we selected all distinct post codes and city names
from an imaginary customers database, sent them through our 
geocoding routine and finally updated all matching rows with our 
geo information.

Another example, updating data in a datastore, might look like 
this::

  from sqlaload import connect, get_table, upsert

  engine = connect('sqlite:///things.db')
  table = get_table('data')

  for item in magic_data_source_that_produces_entries():
      assert 'key1' in item
      assert 'key2' in item
      # this will either insert or update, depending on 
      # whether an entry with the matching values for 
      # 'key1' and 'key2' already exists:
      upsert(engine, table, item, ['key1', 'key2'])


Feedback
--------

Please feel free create issues on the GitHub bug tracker at:

* https://github.com/pudo/sqlaload/issues


<commit_msg>attempt to fix markdown<commit_after>SQLAlchemy Loading Tools
========================

A collection of wrappers and functions to make SQLAlchemy core easier 
to use in an ETL application. The package is used only for database
abstraction and not as an ORM, allowing users to write extraction
scripts that can work with multiple database backends. Functions
include:

* **Self-expanding schema**. If a column is written that does not
  exist on the table, it will be created automatically.
* **Upserts**. Records are either created or updated, depdending on
  whether an existing version can be found.
* **Query helpers** for simple queries such as all rows in a table or
  all distinct values of a set of columns.


Example
-------

A typical use case for ``sqlaload`` may include code like this::

    from sqlaload import connect, get_table, distinct, update
    
    engine = connect('sqlite:///customers.db')
    table = get_table('customers')
    for entry in distinct(engine, table, 'post_code', 'city')
        lon, lat = geocode(entry['post_code'], entry['city'])
        update(entry, {'lon': lon, 'lat': lat})

In this example, we selected all distinct post codes and city names
from an imaginary customers database, sent them through our 
geocoding routine and finally updated all matching rows with our 
geo information.

Another example, updating data in a datastore, might look like 
this::

    from sqlaload import connect, get_table, upsert
    
    engine = connect('sqlite:///things.db')
    table = get_table('data')
    
    for item in magic_data_source_that_produces_entries():
        assert 'key1' in item
        assert 'key2' in item
        # this will either insert or update, depending on 
        # whether an entry with the matching values for 
        # 'key1' and 'key2' already exists:
        upsert(engine, table, item, ['key1', 'key2'])


Feedback
--------

Please feel free create issues on the GitHub bug tracker at:

* https://github.com/pudo/sqlaload/issues



{'fraction_non_alphanumeric': 0.0951417004048583, 'fraction_numerical': 0.003036437246963563, 'mean_word_length': 3.717183770883055, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1807029', 'n_tokens_mistral': 1093, 'n_tokens_neox': 1057, 'n_words': 499}