Skip to content
Snippets Groups Projects
Commit 86ef8856 authored by Andrius Merkys's avatar Andrius Merkys
Browse files

New upstream version 0.5.8

parent f1c67942
No related branches found
No related tags found
No related merge requests found
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
python-version: [3.6, 3.7, 3.8, 3.9, pypy-3.6, pypy-3.7]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
# https://github.com/actions/cache/blob/main/examples.md#using-a-script-to-get-cache-location
- id: pip-cache
run: python -c "from pip._internal.locations import USER_CACHE_DIR; print('::set-output name=dir::' + USER_CACHE_DIR)"
- uses: actions/cache@v1
with:
path: ${{ steps.pip-cache.outputs.dir }}
key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
restore-keys: |
${{ runner.os }}-pip-
- run: pip install --upgrade check-manifest flake8 isort setuptools
- run: check-manifest
- run: flake8 .
- run: isort . --check-only
- run: pip install .[test]
- run: nosetests
......@@ -2,7 +2,6 @@
*.pyc
*.swp
*.swo
.tox
*.egg-info
docs/_build
dist
......
dist: xenial
language: python
python:
- "3.6"
- "3.7"
# command to install dependencies
install:
- if [[ $TRAVIS_PYTHON_VERSION == 3* ]]; then pip install -r requirements-py3.txt; else pip install -r requirements-py2.txt; fi
# command to run tests
script: nosetests tests
sudo: false
0.5.8 - September 15, 2021
--------------------------
* Fix tests for Linux packages.
0.5.7 - July 13, 2021
---------------------
* Add wheels distribution.
0.5.6 - March 4, 2021
---------------------
* Fix test that fails in specific environments.
0.5.5 - July 7, 2020
--------------------
......
include *.db
include *.py
include *.rst
include COPYING
include AUTHORS.rst
include CHANGELOG.rst
include README.rst
recursive-include docs *.py
recursive-include docs *.rst
recursive-include docs Makefile
recursive-include tests *.py
.. image:: https://travis-ci.org/wireservice/agate-sql.png
:target: https://travis-ci.org/wireservice/agate-sql
.. image:: https://github.com/wireservice/agate-sql/workflows/CI/badge.svg
:target: https://github.com/wireservice/agate-sql/actions
:alt: Build status
.. image:: https://img.shields.io/pypi/dm/agate-sql.svg
:target: https://pypi.python.org/pypi/agate-sql
:alt: PyPI downloads
.. image:: https://img.shields.io/pypi/v/agate-sql.svg
:target: https://pypi.python.org/pypi/agate-sql
:alt: Version
......
......@@ -5,18 +5,19 @@ This module contains the agatesql extensions to
:class:`Table <agate.table.Table>`.
"""
import decimal
import datetime
import six
import decimal
import agate
import six
from sqlalchemy import Column, MetaData, Table, UniqueConstraint, create_engine, dialects
from sqlalchemy.engine import Connection
from sqlalchemy.types import BOOLEAN, DATE, DATETIME, DECIMAL, FLOAT, TEXT, TIMESTAMP, VARCHAR, Interval
from sqlalchemy.dialects.mssql import BIT
from sqlalchemy.dialects.oracle import INTERVAL as ORACLE_INTERVAL
from sqlalchemy.dialects.postgresql import INTERVAL as POSTGRES_INTERVAL
from sqlalchemy.engine import Connection
from sqlalchemy.schema import CreateTable
from sqlalchemy.sql import select
from sqlalchemy.types import BOOLEAN, DATE, DATETIME, DECIMAL, FLOAT, TEXT, TIMESTAMP, VARCHAR, Interval
SQL_TYPE_MAP = {
agate.Boolean: None, # See below
......@@ -220,7 +221,8 @@ def make_sql_table(table, table_name, dialect=None, db_schema=None, constraints=
if not isinstance(column.data_type, agate.DateTime):
sql_column_kwargs['nullable'] = table.aggregate(agate.HasNulls(column_name))
sql_table.append_column(make_sql_column(column_name, column, sql_type_kwargs, sql_column_kwargs, sql_column_type))
sql_table.append_column(make_sql_column(column_name, column,
sql_type_kwargs, sql_column_kwargs, sql_column_type))
if unique_constraint:
sql_table.append_constraint(UniqueConstraint(*unique_constraint))
......@@ -230,7 +232,7 @@ def make_sql_table(table, table_name, dialect=None, db_schema=None, constraints=
def to_sql(self, connection_or_string, table_name, overwrite=False,
create=True, create_if_not_exists=False, insert=True, prefixes=[],
db_schema=None, constraints=True, unique_constraint=[], chunk_size=None,
db_schema=None, constraints=True, unique_constraint=[], chunk_size=None,
min_col_len=1, col_len_multiplier=1):
"""
Write this table to the given SQL database.
......@@ -268,7 +270,7 @@ def to_sql(self, connection_or_string, table_name, overwrite=False,
dialect = connection.engine.dialect.name
sql_table = make_sql_table(self, table_name, dialect=dialect, db_schema=db_schema, constraints=constraints,
unique_constraint=unique_constraint, connection=connection,
unique_constraint=unique_constraint, connection=connection,
min_col_len=min_col_len, col_len_multiplier=col_len_multiplier)
if create:
......
# -*- coding: utf-8 -*-
#
# flake8: noqa
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
......@@ -54,9 +52,9 @@ copyright = u'2017, Christopher Groskopf'
# built documents.
#
# The short X.Y version.
version = '0.5.5'
version = '0.5.8'
# The full version, including alpha/beta/rc tags.
release = '0.5.5'
release = version
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
......@@ -191,8 +189,8 @@ htmlhelp_basename = 'agatesqldoc'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'agate-sql.tex', u'agate-sql Documentation',
u'Christopher Groskopf', 'manual'),
('index', 'agate-sql.tex', u'agate-sql Documentation',
u'Christopher Groskopf', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
......
#!/usr/bin/env python
import agate
import agatesql
table = agate.Table.from_sql('sqlite:///example.db', 'test')
......
crate
nose>=1.1.2
tox>=1.3
Sphinx>=1.2.2
sphinx_rtd_theme>=0.1.6
wheel>=0.24.0
agate>=1.5.0
sqlalchemy>=1.0.8
[flake8]
max-line-length = 119
per-file-ignores =
# imported but unused
agatesql/__init__.py: F401
example.py: F401
# block comment should start with '# '
docs/conf.py: E265
[isort]
line_length = 119
[bdist_wheel]
universal = 1
#!/usr/bin/env python
from setuptools import find_packages, setup
from setuptools import setup
install_requires = [
'agate>=1.5.0',
'sqlalchemy>=1.0.8'
]
with open('README.rst') as f:
long_description = f.read()
setup(
name='agate-sql',
version='0.5.5',
version='0.5.8',
description='agate-sql adds SQL read/write support to agate.',
long_description=open('README.rst').read(),
long_description=long_description,
long_description_content_type='text/x-rst',
author='Christopher Groskopf',
author_email='chrisgroskopf@gmail.com',
url='http://agate-sql.readthedocs.org/',
......@@ -26,15 +23,27 @@ setup(
'Programming Language :: Python',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Multimedia :: Graphics',
'Topic :: Scientific/Engineering :: Information Analysis',
'Topic :: Scientific/Engineering :: Visualization',
'Topic :: Software Development :: Libraries :: Python Modules',
],
packages=[
'agatesql'
packages=find_packages(exclude=['tests', 'tests.*']),
install_requires=[
'agate>=1.5.0',
'sqlalchemy>=1.0.8',
],
install_requires=install_requires
extras_require={
'test': [
'crate',
'nose>=1.1.2',
'geojson',
],
'docs': [
'Sphinx>=1.2.2',
'sphinx_rtd_theme>=0.1.6',
],
}
)
......@@ -2,12 +2,15 @@
# -*- coding: utf8 -*-
from decimal import Decimal
from textwrap import dedent
import agate
import agatesql # noqa
from sqlalchemy import create_engine
from sqlalchemy.exc import IntegrityError
import agatesql
class TestSQL(agate.AgateTestCase):
def setUp(self):
self.rows = (
......@@ -18,7 +21,7 @@ class TestSQL(agate.AgateTestCase):
)
self.column_names = [
'number', 'text', 'boolean', 'date', 'datetime',
'number', 'textcol', 'boolean', 'date', 'datetime',
]
self.column_types = [
......@@ -105,48 +108,65 @@ class TestSQL(agate.AgateTestCase):
def test_to_sql_create_statement(self):
statement = self.table.to_sql_create_statement('test_table')
self.assertEqual(statement.replace('\t', ' '), '''CREATE TABLE test_table (
number DECIMAL,
text VARCHAR NOT NULL,
boolean BOOLEAN,
date DATE,
datetime TIMESTAMP
);''') # noqa
self.assertEqual(statement.replace('\t', ' '), dedent('''\
CREATE TABLE test_table (
number DECIMAL,
textcol VARCHAR NOT NULL,
boolean BOOLEAN,
date DATE,
datetime TIMESTAMP
);''')) # noqa: W291
def test_to_sql_create_statement_no_constraints(self):
statement = self.table.to_sql_create_statement('test_table', constraints=False)
self.assertEqual(statement.replace('\t', ' '), '''CREATE TABLE test_table (
number DECIMAL,
text VARCHAR,
boolean BOOLEAN,
date DATE,
datetime TIMESTAMP
);''') # noqa
self.assertEqual(statement.replace('\t', ' '), dedent('''\
CREATE TABLE test_table (
number DECIMAL,
textcol VARCHAR,
boolean BOOLEAN,
date DATE,
datetime TIMESTAMP
);''')) # noqa: W291
def test_to_sql_create_statement_unique_constraint(self):
statement = self.table.to_sql_create_statement('test_table', unique_constraint=['number', 'text'])
self.assertEqual(statement.replace('\t', ' '), '''CREATE TABLE test_table (
number DECIMAL,
text VARCHAR NOT NULL,
boolean BOOLEAN,
date DATE,
datetime TIMESTAMP,
UNIQUE (number, text)
);''') # noqa
statement = self.table.to_sql_create_statement('test_table', unique_constraint=['number', 'textcol'])
self.assertEqual(statement.replace('\t', ' '), dedent('''\
CREATE TABLE test_table (
number DECIMAL,
textcol VARCHAR NOT NULL,
boolean BOOLEAN,
date DATE,
datetime TIMESTAMP,
UNIQUE (number, textcol)
);''')) # noqa: W291
def test_to_sql_create_statement_with_schema(self):
statement = self.table.to_sql_create_statement('test_table', db_schema='test_schema', dialect='mysql')
self.assertEqual(statement.replace('\t', ' '), '''CREATE TABLE test_schema.test_table (
number DECIMAL(38, 3),
text VARCHAR(1) NOT NULL,
boolean BOOL,
date DATE,
datetime TIMESTAMP NULL,
CHECK (boolean IN (0, 1))
);''') # noqa
# https://github.com/wireservice/agate-sql/issues/33#issuecomment-879267838
if 'CHECK' in statement:
expected = '''\
CREATE TABLE test_schema.test_table (
number DECIMAL(38, 3),
textcol VARCHAR(1) NOT NULL,
boolean BOOL,
date DATE,
datetime TIMESTAMP NULL,
CHECK (boolean IN (0, 1))
);''' # noqa: W291
else:
expected = '''\
CREATE TABLE test_schema.test_table (
number DECIMAL(38, 3),
textcol VARCHAR(1) NOT NULL,
boolean BOOL,
date DATE,
datetime TIMESTAMP NULL
);''' # noqa: W291
self.assertEqual(statement.replace('\t', ' '), dedent(expected))
def test_to_sql_create_statement_with_dialects(self):
for dialect in ['crate', 'mssql', 'mysql', 'postgresql', 'sqlite']:
......@@ -160,10 +180,11 @@ class TestSQL(agate.AgateTestCase):
statement = table.to_sql_create_statement('test_table', db_schema='test_schema', dialect='mysql')
self.assertEqual(statement.replace('\t', ' '), '''CREATE TABLE test_schema.test_table (
id DECIMAL(38, 0) NOT NULL,
name VARCHAR(1)
);''') # noqa
self.assertEqual(statement.replace('\t', ' '), dedent('''\
CREATE TABLE test_schema.test_table (
id DECIMAL(38, 0) NOT NULL,
name VARCHAR(1)
);''')) # noqa: W291
def test_to_sql_create_statement_wide_width(self):
rows = ((1, 'x' * 21845), (2, ''))
......@@ -173,10 +194,11 @@ class TestSQL(agate.AgateTestCase):
statement = table.to_sql_create_statement('test_table', db_schema='test_schema', dialect='mysql')
self.assertEqual(statement.replace('\t', ' '), '''CREATE TABLE test_schema.test_table (
id DECIMAL(38, 0) NOT NULL,
name TEXT
);''') # noqa
self.assertEqual(statement.replace('\t', ' '), dedent('''\
CREATE TABLE test_schema.test_table (
id DECIMAL(38, 0) NOT NULL,
name TEXT
);''')) # noqa: W291
def test_make_sql_table_col_len_multiplier(self):
rows = ((1, 'x' * 10), (2, ''))
......@@ -187,8 +209,7 @@ class TestSQL(agate.AgateTestCase):
sql_table = agatesql.table.make_sql_table(table, 'test_table', dialect='mysql', db_schema='test_schema',
constraints=True, col_len_multiplier=1.5)
self.assertEquals(sql_table.columns.get('name').type.length, 15)
self.assertEqual(sql_table.columns.get('name').type.length, 15)
def test_make_sql_table_min_col_len(self):
rows = ((1, 'x' * 10), (2, ''))
......@@ -196,11 +217,10 @@ class TestSQL(agate.AgateTestCase):
column_types = [agate.Number(), agate.Text()]
table = agate.Table(rows, column_names, column_types)
sql_table = agatesql.table.make_sql_table(table, 'test_table', dialect='mysql', db_schema='test_schema',
sql_table = agatesql.table.make_sql_table(table, 'test_table', dialect='mysql', db_schema='test_schema',
constraints=True, min_col_len=20)
self.assertEquals(sql_table.columns.get('name').type.length, 20)
self.assertEqual(sql_table.columns.get('name').type.length, 20)
def test_sql_query_simple(self):
results = self.table.sql_query('select * from agate')
......
[tox]
envlist = py36,py37,pypy
[testenv]
commands = nosetests
[testenv:py36]
deps = -rrequirements-py3.txt
[testenv:py37]
deps = {[testenv:py36]deps}
[testenv:pypy]
deps = {[testenv:py36]deps}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment