Repository: wireservice/csvkit

Issue:
csvsql without tty always tries to read stdin  
The following snip works from a terminal but fails in a non-interactive session (we hit it in Jenkins, but I'd guess it also fails in cron)

```
csvsql --table foo --query "select * from foo" foo.csv
``` 

You get a `StopIteration` exception because csvsql is trying to read from stdin, which has nothing coming (this line: https://github.com/wireservice/csvkit/blob/205175fb70745b80db19acd4c314ad6c774b7fc0/csvkit/utilities/csvsql.py#L57). There's a previous discussion of the issue at https://github.com/wireservice/csvkit/issues/342 and https://github.com/wireservice/csvkit/issues/627, but the linked commit doesn't solve the issue. 

We're working around it by always sending something in to stdin when running from a job. 

I think csvsql should require naming stdin with a "-" when you want to read from both files named as arguments and stdin. This is how `cat` works:

```
echo "foo" | cat /tmp/file.csv  # just prints file.csv
echo "foo" | cat - /tmp/file.csv  # prints foo, then file.csv
echo "foo" | cat /tmp/file.csv -  # prints file.csv, then foo
```



Discussion:

Patch:
diff --git a/CHANGELOG b/CHANGELOG
index 0929e08..b5b78f9 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -44,6 +44,7 @@ Fixes:
 * csvgrep can match multiline values.
 * csvgrep correctly operates on ragged rows.
 * csvsql correctly escapes `%` characters in SQL queries.
+* csvsql adds standard input only if explicitly requested.
 * csvstack supports stacking a single file.
 * csvstat always reports frequencies.
 * FilteringCSVReader's any_match argument works correctly.
diff --git a/csvkit/utilities/csvsql.py b/csvkit/utilities/csvsql.py
index 98c5e84..1da023e 100644
--- a/csvkit/utilities/csvsql.py
+++ b/csvkit/utilities/csvsql.py
@@ -11,7 +11,7 @@ from csvkit.cli import CSVKitUtility
 
 
 class CSVSQL(CSVKitUtility):
-    description = 'Generate SQL statements for one or more CSV files, create execute those statements directly on a database, and execute one or more SQL queries.'
+    description = 'Generate SQL statements for one or more CSV files, or execute those statements directly on a database, and execute one or more SQL queries.'
     override_flags = ['l', 'f']
 
     def add_arguments(self):
@@ -56,14 +56,6 @@ class CSVSQL(CSVKitUtility):
         else:
             table_names = []
 
-        # If one or more filenames are specified, we need to add stdin ourselves (if available)
-        if sys.stdin not in self.input_files:
-            try:
-                if not sys.stdin.isatty():
-                    self.input_files.insert(0, sys.stdin)
-            except:
-                pass
-
         # Create an SQLite database in memory if no connection string is specified
         if query and not connection_string:
             connection_string = "sqlite:///:memory:"
diff --git a/docs/scripts/csvsql.rst b/docs/scripts/csvsql.rst
index 3a9b4b0..f2dd003 100644
--- a/docs/scripts/csvsql.rst
+++ b/docs/scripts/csvsql.rst
@@ -16,7 +16,7 @@ Generate SQL statements for a CSV file or execute those statements directly on a
                   [--blanks] [--no-inference] [--db-schema DB_SCHEMA]
                   [FILE [FILE ...]]
 
-    Generate SQL statements for one or more CSV files, create execute those
+    Generate SQL statements for one or more CSV files, or execute those
     statements directly on a database, and execute one or more SQL queries.
 
     positional arguments:


Test patch:
diff --git a/tests/test_utilities/test_csvsql.py b/tests/test_utilities/test_csvsql.py
index be7d54f..2135fad 100644
--- a/tests/test_utilities/test_csvsql.py
+++ b/tests/test_utilities/test_csvsql.py
@@ -67,7 +67,7 @@ class TestCSVSQL(CSVKitTestCase, EmptyFileTests):
         input_file = six.StringIO("a,b,c\n1,2,3\n")
 
         with stdin_as_string(input_file):
-            sql = self.get_output(['examples/dummy.csv'])
+            sql = self.get_output(['-', 'examples/dummy.csv'])
 
             self.assertTrue('CREATE TABLE stdin' in sql)
             self.assertTrue('CREATE TABLE dummy' in sql)