diff --git a/.github/workflows/bump.yml b/.github/workflows/bump.yml index 9b81ae8..3eaa683 100644 --- a/.github/workflows/bump.yml +++ b/.github/workflows/bump.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Checkout Latest Commit - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Generate changelog uses: charmixer/auto-changelog-action@v1 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 799be82..20bddcd 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -10,9 +10,9 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 steps: - - uses: actions/checkout@v2.3.4 + - uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v2.2.2 + uses: actions/setup-python@v2.3.1 with: python-version: '3.8' - name: Install dependencies @@ -22,6 +22,7 @@ jobs: - name: Create docs run: | make -C docs/ html + cp docs/_config.yml docs/_build/html/_config.yml - name: Deploy Docs 🚀 uses: JamesIves/github-pages-deploy-action@4.1.5 with: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 05ef479..4a471f7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -10,9 +10,9 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 steps: - - uses: actions/checkout@v2.3.4 + - uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v2.2.2 + uses: actions/setup-python@v2.3.1 with: python-version: '3.8' - name: Install dependencies diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 31e15d3..8f22291 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -19,9 +19,9 @@ jobs: python-version: [3.7] steps: - - uses: actions/checkout@v2.3.4 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2.2.2 + uses: actions/setup-python@v2.3.1 with: python-version: ${{ matrix.python-version }} - name: Install dependencies diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 38ec31b..dd674b6 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -15,9 +15,9 @@ jobs: python-version: [3.8] steps: - - uses: actions/checkout@v2.3.4 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2.2.2 + uses: actions/setup-python@v2.3.1 with: python-version: ${{ matrix.python-version }} - name: Install dependencies diff --git a/CHANGELOG.md b/CHANGELOG.md index cae3a3a..1834280 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ # Changelog -## [Unreleased](https://github.com/dermatologist/pyomop/tree/HEAD) +## [3.1.0](https://github.com/dermatologist/pyomop/tree/3.1.0) (2021-09-17) -[Full Changelog](https://github.com/dermatologist/pyomop/compare/3.0.0...HEAD) +[Full Changelog](https://github.com/dermatologist/pyomop/compare/3.0.0...3.1.0) **Closed issues:** diff --git a/README.md b/README.md index 5115c45..ede2628 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,32 @@ -# :notebook: pyomop +# pyomop +![Libraries.io SourceRank](https://img.shields.io/librariesio/sourcerank/pypi/pyomop) [![forthebadge made-with-python](http://ForTheBadge.com/images/badges/made-with-python.svg)](https://www.python.org/) [![PyPI download total](https://img.shields.io/pypi/dm/pyomop.svg)](https://pypi.python.org/pypi/pyomop/) [![Build](https://github.com/dermatologist/pyomop/workflows/Python%20Test/badge.svg)](https://nuchange.ca) * *Inspired by [@jbadger3's](https://github.com/jbadger3) [inspectomop](https://github.com/jbadger3/inspectomop)* +### [Documentation](https://dermatologist.github.io/pyomop/) + ## Description The [OHSDI](https://www.ohdsi.org/) OMOP Common Data Model allows for the systematic analysis of healthcare observational databases. This is a python library to use the CDM v6 compliant databases using SQLAlchemy as the ORM. **pyomop** also supports converting query results to a pandas dataframe (see below) for use in machine learning pipelines. See some useful [SQL Queries here.](https://github.com/OHDSI/QueryLibrary) -## Installation +## Installation (stable) ``` pip install pyomop ``` +## Installation (current) + +* git clone this repository and: +``` +pip install -e . +``` + ## Usage ``` @@ -91,6 +101,8 @@ pip install sqlalchemy==1.3.24 * SqLite * More to follow.. +## Give us a star ⭐️ +If you find this project useful, give us a star. It helps others discover the project. ## Contributors diff --git a/dev-requirements.txt b/dev-requirements.txt index 98304cb..2e7118d 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -18,7 +18,7 @@ charset-normalizer==2.0.6 # via requests commonmark==0.9.1 # via recommonmark -coverage==5.5 +coverage[toml]==5.5 # via pytest-cov distlib==0.3.2 # via virtualenv @@ -64,7 +64,7 @@ pytest==6.2.5 # via # -r dev-requirements.in # pytest-cov -pytest-cov==2.12.1 +pytest-cov==3.0.0 # via -r dev-requirements.in pytz==2021.1 # via @@ -101,18 +101,18 @@ sphinxcontrib-serializinghtml==1.1.5 # via sphinx toml==0.10.2 # via + # coverage # pytest - # pytest-cov # tox tomli==1.2.1 # via setuptools-scm -tox==3.24.4 +tox==3.24.5 # via -r dev-requirements.in urllib3==1.26.6 # via requests virtualenv==20.8.0 # via tox -wheel==0.37.0 +wheel==0.37.1 # via -r dev-requirements.in # The following packages are considered to be unsafe in a requirements file: diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000..199ec09 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,2 @@ +theme: jekyll-theme-leap-day +include: [_sources, _modules, _static] \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 4e22a1d..fc38ee7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,15 +4,15 @@ # # pip-compile # -click==8.0.1 +click==8.0.3 # via pyomop (setup.py) inflect==5.3.0 # via sqlacodegen -numpy==1.21.2 +numpy==1.21.4 # via pandas -pandas==1.3.3 +pandas==1.3.5 # via pyomop (setup.py) -psycopg2-binary==2.9.1 +psycopg2-binary==2.9.3 # via pyomop (setup.py) python-dateutil==2.8.2 # via pandas diff --git a/src/pyomop/vocabulary.py b/src/pyomop/vocabulary.py index 26dec3a..3c1d8f0 100644 --- a/src/pyomop/vocabulary.py +++ b/src/pyomop/vocabulary.py @@ -67,45 +67,45 @@ def set_concept(self, concept_code, vocabulary_id=None): def create_vocab(self, folder, sample=10): if sample < 1000: # nrows=sample try: - df = pd.read_csv(folder + '/DRUG_STRENGTH.csv', sep='\t', nrows=sample, error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/DRUG_STRENGTH.csv', sep='\t', nrows=sample, on_bad_lines='skip') df.to_sql('drug_strength', con=self._engine, if_exists = 'replace') - df = pd.read_csv(folder + '/CONCEPT.csv', sep='\t', nrows=sample, error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/CONCEPT.csv', sep='\t', nrows=sample, on_bad_lines='skip') df.to_sql('concept', con=self._engine, if_exists = 'replace') - df = pd.read_csv(folder + '/CONCEPT_RELATIONSHIP.csv', sep='\t', nrows=sample, error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/CONCEPT_RELATIONSHIP.csv', sep='\t', nrows=sample, on_bad_lines='skip') df.to_sql('concept_relationship', con=self._engine, if_exists = 'replace') - df = pd.read_csv(folder + '/CONCEPT_ANCESTOR.csv', sep='\t', nrows=sample, error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/CONCEPT_ANCESTOR.csv', sep='\t', nrows=sample, on_bad_lines='skip') df.to_sql('concept_ancester', con=self._engine, if_exists = 'replace') - df = pd.read_csv(folder + '/CONCEPT_SYNONYM.csv', sep='\t', nrows=sample, error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/CONCEPT_SYNONYM.csv', sep='\t', nrows=sample, on_bad_lines='skip') df.to_sql('concept_synonym', con=self._engine, if_exists = 'replace') - df = pd.read_csv(folder + '/VOCABULARY.csv', sep='\t', nrows=sample, error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/VOCABULARY.csv', sep='\t', nrows=sample, on_bad_lines='skip') df.to_sql('vocabulary', con=self._engine, if_exists = 'replace') - df = pd.read_csv(folder + '/RELATIONSHIP.csv', sep='\t', nrows=sample, error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/RELATIONSHIP.csv', sep='\t', nrows=sample, on_bad_lines='skip') df.to_sql('relationship', con=self._engine, if_exists = 'replace') - df = pd.read_csv(folder + '/CONCEPT_CLASS.csv', sep='\t', nrows=sample, error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/CONCEPT_CLASS.csv', sep='\t', nrows=sample, on_bad_lines='skip') df.to_sql('concept_class', con=self._engine, if_exists = 'replace') - df = pd.read_csv(folder + '/DOMAIN.csv', sep='\t', nrows=sample, error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/DOMAIN.csv', sep='\t', nrows=sample, on_bad_lines='skip') df.to_sql('domain', con=self._engine, if_exists = 'replace') except ValueError: print("Oops! Could not write vocabulary") else: try: - df = pd.read_csv(folder + '/DRUG_STRENGTH.csv', sep='\t', error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/DRUG_STRENGTH.csv', sep='\t', on_bad_lines='skip') df.to_sql('drug_strength', con=self._engine, if_exists = 'replace') - df = pd.read_csv(folder + '/CONCEPT.csv', sep='\t', error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/CONCEPT.csv', sep='\t', on_bad_lines='skip') df.to_sql('concept', con=self._engine, if_exists = 'replace') - df = pd.read_csv(folder + '/CONCEPT_RELATIONSHIP.csv', sep='\t', error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/CONCEPT_RELATIONSHIP.csv', sep='\t', on_bad_lines='skip') df.to_sql('concept_relationship', con=self._engine, if_exists = 'replace') - df = pd.read_csv(folder + '/CONCEPT_ANCESTOR.csv', sep='\t', error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/CONCEPT_ANCESTOR.csv', sep='\t', on_bad_lines='skip') df.to_sql('concept_ancester', con=self._engine, if_exists = 'replace') - df = pd.read_csv(folder + '/CONCEPT_SYNONYM.csv', sep='\t', error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/CONCEPT_SYNONYM.csv', sep='\t', on_bad_lines='skip') df.to_sql('concept_synonym', con=self._engine, if_exists = 'replace') - df = pd.read_csv(folder + '/VOCABULARY.csv', sep='\t', error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/VOCABULARY.csv', sep='\t', on_bad_lines='skip') df.to_sql('vocabulary', con=self._engine, if_exists = 'replace') - df = pd.read_csv(folder + '/RELATIONSHIP.csv', sep='\t', error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/RELATIONSHIP.csv', sep='\t', on_bad_lines='skip') df.to_sql('relationship', con=self._engine, if_exists = 'replace') - df = pd.read_csv(folder + '/CONCEPT_CLASS.csv', sep='\t', error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/CONCEPT_CLASS.csv', sep='\t', on_bad_lines='skip') df.to_sql('concept_class', con=self._engine, if_exists = 'replace') - df = pd.read_csv(folder + '/DOMAIN.csv', sep='\t', error_bad_lines=False, warn_bad_lines=True) + df = pd.read_csv(folder + '/DOMAIN.csv', sep='\t', on_bad_lines='skip') df.to_sql('domain', con=self._engine, if_exists = 'replace') except ValueError: print("Oops! Could not write vocabulary")