From 13fd3bd77687059c4ef94b4ef801670d0d0c9572 Mon Sep 17 00:00:00 2001 From: preich Date: Sat, 10 Mar 2018 11:16:42 +0000 Subject: [PATCH 01/15] added an example for to_sql --- pandas/core/generic.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index a893b2ba1a189..bf6b18107836f 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1892,6 +1892,36 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, Optional specifying the datatype for columns. The SQL type should be a SQLAlchemy type, or a string for sqlite3 fallback connection. + Examples + -------- + >>> from sqlalchemy import create_engine + >>> import pandas as pd + >>> df=pd.DataFrame({"id":list(range(10)), "name" : ["User " + str(x) for x in range(10)]}) + >>> eng = create_engine('sqlite:///example.db', echo=True) + >>> df.to_sql('users',con=eng,if_exists='replace') + 2018-03-10 11:13:34,676 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 + 2018-03-10 11:13:34,676 INFO sqlalchemy.engine.base.Engine () + 2018-03-10 11:13:34,678 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 + 2018-03-10 11:13:34,678 INFO sqlalchemy.engine.base.Engine () + 2018-03-10 11:13:34,679 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("users") + 2018-03-10 11:13:34,679 INFO sqlalchemy.engine.base.Engine () + 2018-03-10 11:13:34,682 INFO sqlalchemy.engine.base.Engine + CREATE TABLE users ( + "index" BIGINT, + id BIGINT, + name TEXT + ) + + + 2018-03-10 11:13:34,682 INFO sqlalchemy.engine.base.Engine () + 2018-03-10 11:13:34,684 INFO sqlalchemy.engine.base.Engine COMMIT + 2018-03-10 11:13:34,684 INFO sqlalchemy.engine.base.Engine CREATE INDEX ix_users_index ON users ("index") + 2018-03-10 11:13:34,684 INFO sqlalchemy.engine.base.Engine () + 2018-03-10 11:13:34,685 INFO sqlalchemy.engine.base.Engine COMMIT + 2018-03-10 11:13:34,687 INFO sqlalchemy.engine.base.Engine BEGIN (implicit) + 2018-03-10 11:13:34,687 INFO sqlalchemy.engine.base.Engine INSERT INTO users ("index", id, name) VALUES (?, ?, ?) + 2018-03-10 11:13:34,687 INFO sqlalchemy.engine.base.Engine ((0, 0, 'User 0'), (1, 1, 'User 1'), (2, 2, 'User 2'), (3, 3, 'User 3'), (4, 4, 'User 4'), (5, 5, 'User 5'), (6, 6, 'User 6'), (7, 7, 'User 7'), (8, 8, 'User 8'), (9, 9, 'User 9')) + 2018-03-10 11:13:34,688 INFO sqlalchemy.engine.base.Engine COMMIT """ from pandas.io import sql sql.to_sql(self, name, con, schema=schema, if_exists=if_exists, From b65356543a04514e5c5032f740e3d625964e9ae9 Mon Sep 17 00:00:00 2001 From: preich Date: Sat, 10 Mar 2018 12:26:18 +0000 Subject: [PATCH 02/15] removed sqlalchemy/sqlite output; fixed docstring --- pandas/core/generic.py | 49 +++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index bf6b18107836f..17df026d252f8 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1865,10 +1865,12 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, """ Write records stored in a DataFrame to a SQL database. + This function inserts all rows of the dataframe into the given table and recreates if if_exists='replace'. + Parameters ---------- name : string - Name of SQL table + Name of SQL table. con : SQLAlchemy engine or DBAPI2 connection (legacy mode) Using SQLAlchemy makes it possible to use any DB supported by that library. If a DBAPI2 object, only sqlite3 is supported. @@ -1876,6 +1878,7 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, Specify the schema (if database flavor supports this). If None, use default schema. if_exists : {'fail', 'replace', 'append'}, default 'fail' + Accepted values: - fail: If table exists, do nothing. - replace: If table exists, drop it, recreate it, and insert data. - append: If table exists, insert data. Create if does not exist. @@ -1892,36 +1895,28 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, Optional specifying the datatype for columns. The SQL type should be a SQLAlchemy type, or a string for sqlite3 fallback connection. + Returns + -------- + None + + See Also + -------- + pandas.io.sql.to_sql : this function will be called. + Examples -------- >>> from sqlalchemy import create_engine >>> import pandas as pd - >>> df=pd.DataFrame({"id":list(range(10)), "name" : ["User " + str(x) for x in range(10)]}) - >>> eng = create_engine('sqlite:///example.db', echo=True) - >>> df.to_sql('users',con=eng,if_exists='replace') - 2018-03-10 11:13:34,676 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 - 2018-03-10 11:13:34,676 INFO sqlalchemy.engine.base.Engine () - 2018-03-10 11:13:34,678 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 - 2018-03-10 11:13:34,678 INFO sqlalchemy.engine.base.Engine () - 2018-03-10 11:13:34,679 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("users") - 2018-03-10 11:13:34,679 INFO sqlalchemy.engine.base.Engine () - 2018-03-10 11:13:34,682 INFO sqlalchemy.engine.base.Engine - CREATE TABLE users ( - "index" BIGINT, - id BIGINT, - name TEXT - ) - - - 2018-03-10 11:13:34,682 INFO sqlalchemy.engine.base.Engine () - 2018-03-10 11:13:34,684 INFO sqlalchemy.engine.base.Engine COMMIT - 2018-03-10 11:13:34,684 INFO sqlalchemy.engine.base.Engine CREATE INDEX ix_users_index ON users ("index") - 2018-03-10 11:13:34,684 INFO sqlalchemy.engine.base.Engine () - 2018-03-10 11:13:34,685 INFO sqlalchemy.engine.base.Engine COMMIT - 2018-03-10 11:13:34,687 INFO sqlalchemy.engine.base.Engine BEGIN (implicit) - 2018-03-10 11:13:34,687 INFO sqlalchemy.engine.base.Engine INSERT INTO users ("index", id, name) VALUES (?, ?, ?) - 2018-03-10 11:13:34,687 INFO sqlalchemy.engine.base.Engine ((0, 0, 'User 0'), (1, 1, 'User 1'), (2, 2, 'User 2'), (3, 3, 'User 3'), (4, 4, 'User 4'), (5, 5, 'User 5'), (6, 6, 'User 6'), (7, 7, 'User 7'), (8, 8, 'User 8'), (9, 9, 'User 9')) - 2018-03-10 11:13:34,688 INFO sqlalchemy.engine.base.Engine COMMIT + >>> engine = create_engine('sqlite:///example.db', echo=False) + >>> df=pd.DataFrame({"id":list(range(3)), "name" : ["User " + str(x) for x in range(3)]}) + >>> # create a table from scratch + >>> df.to_sql('users',con=engine,if_exists='replace') + >>> df1=pd.DataFrame({"id":list(range(3,5)), "name" : ["User " + str(x) for x in range(3,5)]}) + >>> # 2 new rows inserted + >>> df1.to_sql('users',con=engine,if_exists='append') + >>> # table will be recreated and 5 rows inserted + >>> df=pd.concat([df,df1],ignore_index=True) + >>> df.to_sql('users',con=engine,if_exists='replace') """ from pandas.io import sql sql.to_sql(self, name, con, schema=schema, if_exists=if_exists, From c48870f7ba0a1680970950e07fd01e245e4ae7f0 Mon Sep 17 00:00:00 2001 From: preich Date: Sat, 10 Mar 2018 12:57:18 +0000 Subject: [PATCH 03/15] fixed line width --- pandas/core/generic.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 17df026d252f8..ef2b3099d274e 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1865,7 +1865,8 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, """ Write records stored in a DataFrame to a SQL database. - This function inserts all rows of the dataframe into the given table and recreates if if_exists='replace'. + This function inserts all rows of the dataframe into the given + table and recreates if if_exists='replace'. Parameters ---------- @@ -1905,13 +1906,15 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, Examples -------- - >>> from sqlalchemy import create_engine >>> import pandas as pd + >>> from sqlalchemy import create_engine >>> engine = create_engine('sqlite:///example.db', echo=False) - >>> df=pd.DataFrame({"id":list(range(3)), "name" : ["User " + str(x) for x in range(3)]}) + >>> gen_names = lambda ids: ["User" + str(x) for x in ids] + >>> gen_users = lambda ids: {"id": ids, "name" : gen_names(ids)} + >>> df=pd.DataFrame(gen_users(list(range(3)))) >>> # create a table from scratch >>> df.to_sql('users',con=engine,if_exists='replace') - >>> df1=pd.DataFrame({"id":list(range(3,5)), "name" : ["User " + str(x) for x in range(3,5)]}) + >>> df1=pd.DataFrame(gen_users(list(range(3,5)))) >>> # 2 new rows inserted >>> df1.to_sql('users',con=engine,if_exists='append') >>> # table will be recreated and 5 rows inserted From 9cce9e98772f6a2af098a813526ab19cc76631d0 Mon Sep 17 00:00:00 2001 From: preich Date: Sat, 10 Mar 2018 13:33:24 +0000 Subject: [PATCH 04/15] removed import pandas --- pandas/core/generic.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index ef2b3099d274e..ad806dd20ff95 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1866,7 +1866,8 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, Write records stored in a DataFrame to a SQL database. This function inserts all rows of the dataframe into the given - table and recreates if if_exists='replace'. + table and recreates it if if_exists='replace'. Databases supported by + SQLAlchemy or DBAPI2 are also supported. Parameters ---------- @@ -1906,13 +1907,12 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, Examples -------- - >>> import pandas as pd >>> from sqlalchemy import create_engine >>> engine = create_engine('sqlite:///example.db', echo=False) >>> gen_names = lambda ids: ["User" + str(x) for x in ids] >>> gen_users = lambda ids: {"id": ids, "name" : gen_names(ids)} >>> df=pd.DataFrame(gen_users(list(range(3)))) - >>> # create a table from scratch + >>> # create a table from scratch with 3 rows >>> df.to_sql('users',con=engine,if_exists='replace') >>> df1=pd.DataFrame(gen_users(list(range(3,5)))) >>> # 2 new rows inserted From b4dd9b1d6e0f226b80f5c77ff4b1bc6e2c59378a Mon Sep 17 00:00:00 2001 From: preich Date: Sat, 10 Mar 2018 13:35:01 +0000 Subject: [PATCH 05/15] spaces added in the example --- pandas/core/generic.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index ad806dd20ff95..9c55e3b9152c9 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1911,15 +1911,15 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, >>> engine = create_engine('sqlite:///example.db', echo=False) >>> gen_names = lambda ids: ["User" + str(x) for x in ids] >>> gen_users = lambda ids: {"id": ids, "name" : gen_names(ids)} - >>> df=pd.DataFrame(gen_users(list(range(3)))) + >>> df = pd.DataFrame(gen_users(list(range(3)))) >>> # create a table from scratch with 3 rows - >>> df.to_sql('users',con=engine,if_exists='replace') - >>> df1=pd.DataFrame(gen_users(list(range(3,5)))) + >>> df.to_sql('users', con=engine, if_exists='replace') + >>> df1 = pd.DataFrame(gen_users(list(range(3, 5)))) >>> # 2 new rows inserted - >>> df1.to_sql('users',con=engine,if_exists='append') + >>> df1.to_sql('users', con=engine, if_exists='append') >>> # table will be recreated and 5 rows inserted - >>> df=pd.concat([df,df1],ignore_index=True) - >>> df.to_sql('users',con=engine,if_exists='replace') + >>> df = pd.concat([df, df1], ignore_index=True) + >>> df.to_sql('users', con=engine, if_exists='replace') """ from pandas.io import sql sql.to_sql(self, name, con, schema=schema, if_exists=if_exists, From 9af573da013b8a38c3da57971bb8215340f43769 Mon Sep 17 00:00:00 2001 From: preich Date: Sat, 10 Mar 2018 13:45:25 +0000 Subject: [PATCH 06/15] removed id column, added read_sql_query to the example --- pandas/core/generic.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 9c55e3b9152c9..fd0637a0fcc2b 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1903,23 +1903,28 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, See Also -------- - pandas.io.sql.to_sql : this function will be called. + pandas.read_sql_query : read a DataFrame from a table Examples -------- >>> from sqlalchemy import create_engine >>> engine = create_engine('sqlite:///example.db', echo=False) - >>> gen_names = lambda ids: ["User" + str(x) for x in ids] - >>> gen_users = lambda ids: {"id": ids, "name" : gen_names(ids)} - >>> df = pd.DataFrame(gen_users(list(range(3)))) + >>> df = pd.DataFrame({'name' : ['User 1', 'User 2', 'User 3']}) >>> # create a table from scratch with 3 rows >>> df.to_sql('users', con=engine, if_exists='replace') - >>> df1 = pd.DataFrame(gen_users(list(range(3, 5)))) + >>> df1 = pd.DataFrame({'name' : ['User 4', 'User 5']}) >>> # 2 new rows inserted >>> df1.to_sql('users', con=engine, if_exists='append') >>> # table will be recreated and 5 rows inserted >>> df = pd.concat([df, df1], ignore_index=True) >>> df.to_sql('users', con=engine, if_exists='replace') + >>> pd.read_sql_query("select * from users",con=engine) + index name + 0 0 User 1 + 1 1 User 2 + 2 2 User 3 + 3 3 User 4 + 4 4 User 5 """ from pandas.io import sql sql.to_sql(self, name, con, schema=schema, if_exists=if_exists, From be02b355789f0001e30f626e5d5fcca641005e53 Mon Sep 17 00:00:00 2001 From: preich Date: Sat, 10 Mar 2018 15:26:09 +0000 Subject: [PATCH 07/15] no need to create files --- pandas/core/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index fd0637a0fcc2b..680574454a9f5 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1908,7 +1908,7 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, Examples -------- >>> from sqlalchemy import create_engine - >>> engine = create_engine('sqlite:///example.db', echo=False) + >>> engine = create_engine('sqlite://', echo=False) >>> df = pd.DataFrame({'name' : ['User 1', 'User 2', 'User 3']}) >>> # create a table from scratch with 3 rows >>> df.to_sql('users', con=engine, if_exists='replace') From 62e9cb06a10e4788877017c9dbdd933154db904f Mon Sep 17 00:00:00 2001 From: preich Date: Sat, 10 Mar 2018 15:39:29 +0000 Subject: [PATCH 08/15] remove pointless Accepted values --- pandas/core/generic.py | 1 - scripts/validate_docstrings.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 680574454a9f5..e17728a7de901 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1880,7 +1880,6 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, Specify the schema (if database flavor supports this). If None, use default schema. if_exists : {'fail', 'replace', 'append'}, default 'fail' - Accepted values: - fail: If table exists, do nothing. - replace: If table exists, drop it, recreate it, and insert data. - append: If table exists, insert data. Create if does not exist. diff --git a/scripts/validate_docstrings.py b/scripts/validate_docstrings.py index 8425882f07be1..a89d72a491ae0 100755 --- a/scripts/validate_docstrings.py +++ b/scripts/validate_docstrings.py @@ -428,7 +428,7 @@ def validate_one(func_name): param_errs.append('Parameter "{}" ' 'has no description'.format(param)) else: - if not doc.parameter_desc(param)[0].isupper(): + if not doc.parameter_desc(param)[0].isupper() and doc.parameter_desc(param)[0] != '-': param_errs.append('Parameter "{}" description ' 'should start with ' 'capital letter'.format(param)) From e315f67e4f8a825c3b4f64b65a95a036f19d7734 Mon Sep 17 00:00:00 2001 From: preich Date: Sat, 10 Mar 2018 15:42:36 +0000 Subject: [PATCH 09/15] rollback --- scripts/validate_docstrings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/validate_docstrings.py b/scripts/validate_docstrings.py index a89d72a491ae0..8425882f07be1 100755 --- a/scripts/validate_docstrings.py +++ b/scripts/validate_docstrings.py @@ -428,7 +428,7 @@ def validate_one(func_name): param_errs.append('Parameter "{}" ' 'has no description'.format(param)) else: - if not doc.parameter_desc(param)[0].isupper() and doc.parameter_desc(param)[0] != '-': + if not doc.parameter_desc(param)[0].isupper(): param_errs.append('Parameter "{}" description ' 'should start with ' 'capital letter'.format(param)) From 15a89389973ca38cf203d319e1de0d8c57842a27 Mon Sep 17 00:00:00 2001 From: preich Date: Sat, 10 Mar 2018 16:05:21 +0000 Subject: [PATCH 10/15] added references --- pandas/core/generic.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index e17728a7de901..24a62dda5ffb1 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1880,6 +1880,7 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, Specify the schema (if database flavor supports this). If None, use default schema. if_exists : {'fail', 'replace', 'append'}, default 'fail' + Accepted values: - fail: If table exists, do nothing. - replace: If table exists, drop it, recreate it, and insert data. - append: If table exists, insert data. Create if does not exist. @@ -1900,6 +1901,10 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, -------- None + References + -------- + http://docs.sqlalchemy.org : Used for testing + See Also -------- pandas.read_sql_query : read a DataFrame from a table @@ -1911,9 +1916,11 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, >>> df = pd.DataFrame({'name' : ['User 1', 'User 2', 'User 3']}) >>> # create a table from scratch with 3 rows >>> df.to_sql('users', con=engine, if_exists='replace') + >>> df1 = pd.DataFrame({'name' : ['User 4', 'User 5']}) >>> # 2 new rows inserted >>> df1.to_sql('users', con=engine, if_exists='append') + >>> # table will be recreated and 5 rows inserted >>> df = pd.concat([df, df1], ignore_index=True) >>> df.to_sql('users', con=engine, if_exists='replace') From c82208b50b7b074a459a3c6206e5c9f44b8618f3 Mon Sep 17 00:00:00 2001 From: preich Date: Sat, 10 Mar 2018 22:24:14 +0000 Subject: [PATCH 11/15] comments added --- pandas/core/generic.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 24a62dda5ffb1..08904c6aa0fa1 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1914,14 +1914,15 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, >>> from sqlalchemy import create_engine >>> engine = create_engine('sqlite://', echo=False) >>> df = pd.DataFrame({'name' : ['User 1', 'User 2', 'User 3']}) - >>> # create a table from scratch with 3 rows + + **create a table from scratch with 3 rows** >>> df.to_sql('users', con=engine, if_exists='replace') + **2 new rows inserted** >>> df1 = pd.DataFrame({'name' : ['User 4', 'User 5']}) - >>> # 2 new rows inserted >>> df1.to_sql('users', con=engine, if_exists='append') - >>> # table will be recreated and 5 rows inserted + **table will be recreated and 5 rows inserted** >>> df = pd.concat([df, df1], ignore_index=True) >>> df.to_sql('users', con=engine, if_exists='replace') >>> pd.read_sql_query("select * from users",con=engine) From 7c503b6ee7feb7fdabdc2949d558618a624b23ed Mon Sep 17 00:00:00 2001 From: preich Date: Sat, 10 Mar 2018 22:26:58 +0000 Subject: [PATCH 12/15] comments added --- pandas/core/generic.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 08904c6aa0fa1..819c259d941f9 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1913,16 +1913,19 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, -------- >>> from sqlalchemy import create_engine >>> engine = create_engine('sqlite://', echo=False) - >>> df = pd.DataFrame({'name' : ['User 1', 'User 2', 'User 3']}) **create a table from scratch with 3 rows** + + >>> df = pd.DataFrame({'name' : ['User 1', 'User 2', 'User 3']}) >>> df.to_sql('users', con=engine, if_exists='replace') **2 new rows inserted** + >>> df1 = pd.DataFrame({'name' : ['User 4', 'User 5']}) >>> df1.to_sql('users', con=engine, if_exists='append') **table will be recreated and 5 rows inserted** + >>> df = pd.concat([df, df1], ignore_index=True) >>> df.to_sql('users', con=engine, if_exists='replace') >>> pd.read_sql_query("select * from users",con=engine) From 5668eec18734ae456fc75476391987d7c829541a Mon Sep 17 00:00:00 2001 From: preich Date: Sat, 10 Mar 2018 22:38:07 +0000 Subject: [PATCH 13/15] comments added --- pandas/core/frame.py | 5 +++++ pandas/core/generic.py | 11 +++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index a66d00fff9714..3645db3fdce36 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -1814,6 +1814,11 @@ def info(self, verbose=None, buf=None, max_cols=None, memory_usage=None, null_counts=None): """ Concise summary of a DataFrame. + References + -------- + .. [1] http://docs.sqlalchemy.org : Used for testing + + Parameters ---------- diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 819c259d941f9..be298506240a2 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1901,16 +1901,15 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, -------- None - References - -------- - http://docs.sqlalchemy.org : Used for testing - See Also -------- pandas.read_sql_query : read a DataFrame from a table Examples -------- + + **create an in-memory database using [1]** + >>> from sqlalchemy import create_engine >>> engine = create_engine('sqlite://', echo=False) @@ -1935,6 +1934,10 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, 2 2 User 3 3 3 User 4 4 4 User 5 + + References + ---------- + .. [1] http://docs.sqlalchemy.org : SQLAlchemy is used for testing """ from pandas.io import sql sql.to_sql(self, name, con, schema=schema, if_exists=if_exists, From 9e1bec43a4bffea6a07c7f61b3bcce059a688473 Mon Sep 17 00:00:00 2001 From: preich Date: Sat, 10 Mar 2018 22:39:26 +0000 Subject: [PATCH 14/15] use read_sql --- pandas/core/generic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index be298506240a2..a33dfce8961da 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1903,7 +1903,7 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, See Also -------- - pandas.read_sql_query : read a DataFrame from a table + pandas.read_sql : read a DataFrame from a table Examples -------- @@ -1927,7 +1927,7 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, >>> df = pd.concat([df, df1], ignore_index=True) >>> df.to_sql('users', con=engine, if_exists='replace') - >>> pd.read_sql_query("select * from users",con=engine) + >>> pd.read_sql("select * from users",con=engine) index name 0 0 User 1 1 1 User 2 From fa9cc36c438b1f5f0368cd0cfafd2b9818cfc5d7 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Mon, 12 Mar 2018 17:15:01 -0500 Subject: [PATCH 15/15] Updates * Added more examples * Reworded extended * Reformed if_exists * Added Raises * Removed Returns * Added DBABI2 ref --- pandas/core/frame.py | 5 -- pandas/core/generic.py | 103 ++++++++++++++++++++++++++--------------- 2 files changed, 66 insertions(+), 42 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 3645db3fdce36..a66d00fff9714 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -1814,11 +1814,6 @@ def info(self, verbose=None, buf=None, max_cols=None, memory_usage=None, null_counts=None): """ Concise summary of a DataFrame. - References - -------- - .. [1] http://docs.sqlalchemy.org : Used for testing - - Parameters ---------- diff --git a/pandas/core/generic.py b/pandas/core/generic.py index a33dfce8961da..fcc551b3ac2e4 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1865,79 +1865,108 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True, """ Write records stored in a DataFrame to a SQL database. - This function inserts all rows of the dataframe into the given - table and recreates it if if_exists='replace'. Databases supported by - SQLAlchemy or DBAPI2 are also supported. + Databases supported by SQLAlchemy [1]_ are supported. Tables can be + newly created, appended to, or overwritten. Parameters ---------- name : string Name of SQL table. - con : SQLAlchemy engine or DBAPI2 connection (legacy mode) + con : sqlalchemy.engine.Engine or sqlite3.Connection Using SQLAlchemy makes it possible to use any DB supported by that - library. If a DBAPI2 object, only sqlite3 is supported. - schema : string, default None + library. Legacy support is provided for sqlite3.Connection objects. + schema : string, optional Specify the schema (if database flavor supports this). If None, use default schema. if_exists : {'fail', 'replace', 'append'}, default 'fail' - Accepted values: - - fail: If table exists, do nothing. - - replace: If table exists, drop it, recreate it, and insert data. - - append: If table exists, insert data. Create if does not exist. + How to behave if the table already exists. + + * fail: Raise a ValueError. + * replace: Drop the table before inserting new values. + * append: Insert new values to the existing table. + index : boolean, default True - Write DataFrame index as a column. + Write DataFrame index as a column. Uses `index_label` as the column + name in the table. index_label : string or sequence, default None Column label for index column(s). If None is given (default) and `index` is True, then the index names are used. A sequence should be given if the DataFrame uses MultiIndex. - chunksize : int, default None - If not None, then rows will be written in batches of this size at a - time. If None, all rows will be written at once. - dtype : dict of column name to SQL type, default None - Optional specifying the datatype for columns. The SQL type should - be a SQLAlchemy type, or a string for sqlite3 fallback connection. + chunksize : int, optional + Rows will be written in batches of this size at a time. By default, + all rows will be written at once. + dtype : dict, optional + Specifying the datatype for columns. The keys should be the column + names and the values should be the SQLAlchemy types or strings for + the sqlite3 legacy mode. - Returns - -------- - None + Raises + ------ + ValueError + When the table already exists and `if_exists` is 'fail' (the + default). See Also -------- pandas.read_sql : read a DataFrame from a table + References + ---------- + .. [1] http://docs.sqlalchemy.org + .. [2] https://www.python.org/dev/peps/pep-0249/ + Examples -------- - **create an in-memory database using [1]** + Create an in-memory SQLite database. >>> from sqlalchemy import create_engine >>> engine = create_engine('sqlite://', echo=False) - **create a table from scratch with 3 rows** + Create a table from scratch with 3 rows. >>> df = pd.DataFrame({'name' : ['User 1', 'User 2', 'User 3']}) - >>> df.to_sql('users', con=engine, if_exists='replace') + >>> df + name + 0 User 1 + 1 User 2 + 2 User 3 - **2 new rows inserted** + >>> df.to_sql('users', con=engine) + >>> engine.execute("SELECT * FROM users").fetchall() + [(0, 'User 1'), (1, 'User 2'), (2, 'User 3')] >>> df1 = pd.DataFrame({'name' : ['User 4', 'User 5']}) >>> df1.to_sql('users', con=engine, if_exists='append') + >>> engine.execute("SELECT * FROM users").fetchall() + [(0, 'User 1'), (1, 'User 2'), (2, 'User 3'), + (0, 'User 4'), (1, 'User 5')] - **table will be recreated and 5 rows inserted** + Overwrite the table with just ``df1``. - >>> df = pd.concat([df, df1], ignore_index=True) - >>> df.to_sql('users', con=engine, if_exists='replace') - >>> pd.read_sql("select * from users",con=engine) - index name - 0 0 User 1 - 1 1 User 2 - 2 2 User 3 - 3 3 User 4 - 4 4 User 5 + >>> df1.to_sql('users', con=engine, if_exists='replace', + ... index_label='id') + >>> engine.execute("SELECT * FROM users").fetchall() + [(0, 'User 4'), (1, 'User 5')] - References - ---------- - .. [1] http://docs.sqlalchemy.org : SQLAlchemy is used for testing + Specify the dtype (especially useful for integers with missing values). + Notice that while pandas is forced to store the data as floating point, + the database supports nullable integers. When fetching the data with + Python, we get back integer scalars. + + >>> df = pd.DataFrame({"A": [1, None, 2]}) + >>> df + A + 0 1.0 + 1 NaN + 2 2.0 + + >>> from sqlalchemy.types import Integer + >>> df.to_sql('integers', con=engine, index=False, + ... dtype={"A": Integer()}) + + >>> engine.execute("SELECT * FROM integers").fetchall() + [(1,), (None,), (2,)] """ from pandas.io import sql sql.to_sql(self, name, con, schema=schema, if_exists=if_exists,