How do I create a CSV file from database in Python? - python
I have a Sqlite 3 and/or MySQL table named "clients"..
Using python 2.6, How do I create a csv file named Clients100914.csv with headers?
excel dialect...
The Sql execute: select * only gives table data, but I would like complete table with headers.
How do I create a record set to get table headers. The table headers should come directly from sql not written in python.
w = csv.writer(open(Fn,'wb'),dialect='excel')
#w.writelines("header_row")
#Fetch into sqld
w.writerows(sqld)
This code leaves me with file open and no headers. Also cant get figure out how to use file as log.
import csv
import sqlite3
from glob import glob; from os.path import expanduser
conn = sqlite3.connect( # open "places.sqlite" from one of the Firefox profiles
glob(expanduser('~/.mozilla/firefox/*/places.sqlite'))[0]
)
cursor = conn.cursor()
cursor.execute("select * from moz_places;")
with open("out.csv", "w", newline='') as csv_file: # Python 3 version
#with open("out.csv", "wb") as csv_file: # Python 2 version
csv_writer = csv.writer(csv_file)
csv_writer.writerow([i[0] for i in cursor.description]) # write headers
csv_writer.writerows(cursor)
PEP 249 (DB API 2.0) has more information about cursor.description.
Using the csv module is very straight forward and made for this task.
import csv
writer = csv.writer(open("out.csv", 'w'))
writer.writerow(['name', 'address', 'phone', 'etc'])
writer.writerow(['bob', '2 main st', '703', 'yada'])
writer.writerow(['mary', '3 main st', '704', 'yada'])
Creates exactly the format you're expecting.
You can easily create it manually, writing a file with a chosen separator. You can also use csv module.
If it's from database you can alo just use a query from your sqlite client :
sqlite <db params> < queryfile.sql > output.csv
Which will create a csv file with tab separator.
How to extract the column headings from an existing table:
You don't need to parse an SQL "create table" statement. This is fortunate, as the "create table" syntax is neither nice nor clean, it is warthog-ugly.
You can use the table_info pragma. It gives you useful information about each column in a table, including the name of the column.
Example:
>>> #coding: ascii
... import sqlite3
>>>
>>> def get_col_names(cursor, table_name):
... results = cursor.execute("PRAGMA table_info(%s);" % table_name)
... return [row[1] for row in results]
...
>>> def wrong_way(cur, table):
... import re
... cur.execute("SELECT sql FROM sqlite_master WHERE name=?;", (table, ))
... sql = cur.fetchone()[0]
... column_defs = re.findall("[(](.*)[)]", sql)[0]
... first_words = (line.split()[0].strip() for line in column_defs.split(','))
... columns = [word for word in first_words if word.upper() != "CONSTRAINT"]
... return columns
...
>>> conn = sqlite3.connect(":memory:")
>>> curs = conn.cursor()
>>> _ignored = curs.execute(
... "create table foo (id integer, name text, [haha gotcha] text);"
... )
>>> print get_col_names(curs, "foo")
[u'id', u'name', u'haha gotcha']
>>> print wrong_way(curs, "foo")
[u'id', u'name', u'[haha'] <<<<<===== WHOOPS!
>>>
Other problems with the now-deleted "parse the create table SQL" answer:
Stuffs up with e.g. create table test (id1 text, id2 int, msg text, primary key(id1, id2)) ... needs to ignore not only CONSTRAINT, but also keywords PRIMARY, UNIQUE, CHECK and FOREIGN (see the create table docs).
Needs to specify re.DOTALL in case there are newlines in the SQL.
In line.split()[0].strip() the strip is redundant.
This is simple and works fine for me.
Lets say you have already connected to your database table and also got a cursor object. So following on on from that point.
import csv
curs = conn.cursor()
curs.execute("select * from oders")
m_dict = list(curs.fetchall())
with open("mycsvfile.csv", "wb") as f:
w = csv.DictWriter(f, m_dict[0].keys())
w.writerow(dict((fn,fn) for fn in m_dict[0].keys()))
w.writerows(m_dict)
unless i'm missing something, you just want to do something like so...
f = open("somefile.csv")
f.writelines("header_row")
logic to write lines to file (you may need to organize values and add comms or pipes etc...)
f.close()
It can be easily done using pandas and sqlite3. In extension to the answer from Cristian Ciupitu.
import sqlite3
from glob import glob; from os.path import expanduser
conn = sqlite3.connect(glob(expanduser('data/clients_data.sqlite'))[0])
cursor = conn.cursor()
Now use pandas to read the table and write to csv.
clients = pd.read_sql('SELECT * FROM clients' ,conn)
clients.to_csv('data/Clients100914.csv', index=False)
This is more direct and works all the time.
The below code works for Oracle with Python 3.6 :
import cx_Oracle
import csv
# Create tns
dsn_tns=cx_Oracle.makedsn('<host>', '<port>', service_name='<service_name>')
# Connect to DB using user, password and tns settings
conn=cx_Oracle.connect(user='<user>', password='<pass>',dsn=dsn_tns)
c=conn.cursor()
#Execute the Query
c.execute("select * from <table>")
# Write results into CSV file
with open("<file>.csv", "w", newline='') as csv_file:
csv_writer = csv.writer(csv_file)
csv_writer.writerow([i[0] for i in c.description]) # write headers
csv_writer.writerows(c)
Related
Error: invalid syntax using cx_oracle in python
Below code is for extracting the data from oracle database in csv file. In query,For converting from Fractional decimal into date format,i have used To_Date('12/30/1899', 'MM/DD/YYYY HH24:MI:SS')+DTIMESTAMP) Decoded_Date. And also specified the date range for extracting the data between dates. Please help what's wrong in below code giving invalid syntax. import csv import cx_Oracle dsn_tns = cx_Oracle.makedsn('hostname', 'port', sid='sid') # if needed, place an 'r' before any parameter in order to address special characters such as '\'. conn = cx_Oracle.connect(user=r'username', password='password', dsn=dsn_tns) cursor = conn.cursor() csv_file = open("C:/Users/locations.csv", "w") writer = csv.writer(csv_file, delimiter=',', lineterminator="\n", quoting=csv.QUOTE_NONNUMERIC) r = cursor.execute("""SELECT * FROM (SELECT LROWNUM,DTIMESTAMP,LSCENARIO,LYEAR,LPERIOD, LENTITY,LPARENT,LVALUE,LACCOUNT,LICP,LCUSTOM1, LCUSTOM2,STRUSERNAME,STRSERVERNAME, LACTIVITY,DDATAVALUE,BNODATA, (To_Date('12/30/1899', 'MM/DD/YYYY HH24:MI:SS')+DTIMESTAMP) Decoded_Date FROM TABLE_NAME ) SUB WHERE SUB.Decoded_Date between '23-MAR-2020' and '24-APR-2020'; """) for row in cursor: writer.writerow(row) cursor.close() conn.close() csv_file.close()
The opening and closing parentheses should not be present. I can't test the SQL directly, of course, but this should in theory work for you! r = cursor.execute""" SELECT * FROM ( SELECT LROWNUM,DTIMESTAMP,LSCENARIO,LYEAR,LPERIOD, LENTITY,LPARENT,LVALUE,LACCOUNT,LICP,LCUSTOM1, LCUSTOM2,STRUSERNAME,STRSERVERNAME, LACTIVITY,DDATAVALUE,BNODATA, To_Date('12/30/1899','MM/DD/YYYY') + DTIMESTAMP as Decoded_Date FROM TABLE_NAME ) SUB WHERE SUB.Decoded_Date between to_date('23-MAR-2020', 'DD-MON-YYYY') and to_date('24-APR-2020', 'DD-MON-YYYY') """ Note the changes to the last line as well. Unless you know the value of NLS_DATE_FORMAT you can't compare strings with dates directly. Note that you can also bind date values directly as in sql = "select ... where sub.decoded_date between :1 and :2" cursor.execute(sql, [datetime.date(2020, 3, 23), datetime.date(2020, 4, 24)])
SQLalchemy- How I can extract table from sqlite file?
I want to extract table information from sqlite file. I could list all the table name following this page and tried to extract table information using query method on the session instance. But I got following error. sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: ComponentSizes [SQL: 'SELECT ComponentSizes'] Does anyone know how should I revise following code in order to extract table specifying the table name? class read(): def __init__(self,path): engine = create_engine("sqlite:///" + sqlFile) inspector=inspect(engine) for table_name in inspector.get_table_names(): for column in inspector.get_columns(table_name): #print("Column: %s" % column['name']) print (table_name+" : "+column['name']) Session = sessionmaker(bind=engine) self.session = Session() def getTable(self,name): table=self.session.query(name).all() return table if __name__ == '__main__': test=read(sqlFile) test.getTable('ComponentSizes')
The error you are getting is suggestive of what is going wrong. Your code is translating into SQL - SELECT ComponentSizes which is incomplete. It's not clear for what is your end goal. If you want to extract contents of a table into CSV, you could do this: import sqlite3 import csv con = sqlite3.connect('mydatabase.db') outfile = open('mydump.csv', 'wb') outcsv = csv.writer(outfile) cursor = con.execute('select * from ComponentSizes') # dump column titles (optional) outcsv.writerow(x[0] for x in cursor.description) # dump rows outcsv.writerows(cursor.fetchall()) outfile.close() Else, if you want contents of the table into a pandas df for further analysis, you could choose to do this: import sqlite3 import pandas as pd # Create your connection. cnx = sqlite3.connect('file.db') df = pd.read_sql_query("SELECT * FROM ComponentSizes", cnx) Hope it helps. Happy coding!
csv into sqlite table python
Using python, I am trying to import a csv into an sqlite table and use the headers in the csv file to become the headers in the sqlite table. The code runs but the table "MyTable" does not appear to be created. Here is the code: with open ('dict_output.csv', 'r') as f: reader = csv.reader(f) columns = next(reader) #Strips white space in header columns = [h.strip() for h in columns] #reader = csv.DictReader(f, fieldnames=columns) for row in reader: print(row) con = sqlite3.connect("city_spec.db") cursor = con.cursor() #Inserts data from csv into table in sql database. query = 'insert into MyTable({0}) values ({1})' query = query.format(','.join(columns), ','.join('?' * len(columns))) print(query) cursor = con.cursor() for row in reader: cursor.execute(query, row) #cursor.commit() con.commit() con.close() Thanks in advance for any help.
You can use Pandas to make this easy (you may need to pip install pandas first): import sqlite3 import pandas as pd # load data df = pd.read_csv('dict_output.csv') # strip whitespace from headers df.columns = df.columns.str.strip() con = sqlite3.connect("city_spec.db") # drop data into database df.to_sql("MyTable", con) con.close() Pandas will do all of the hard work for you, including create the actual table!
You haven't marked your answer solved yet so here goes. Connect to the database just once, and create a cursor just once. You can read the csv records only once. I've added code that creates a crude form of the database table based on the column names alone. Again, this is done just once in the loop. Your insertion code works fine. import sqlite3 import csv con = sqlite3.connect("city_spec.sqlite") ## these statements belong outside the loop cursor = con.cursor() ## execute them just once first = True with open ('dict_output.csv', 'r') as f: reader = csv.reader(f) columns = next(reader) columns = [h.strip() for h in columns] if first: sql = 'CREATE TABLE IF NOT EXISTS MyTable (%s)' % ', '.join(['%s text'%column for column in columns]) print (sql) cursor.execute(sql) first = False #~ for row in reader: ## we will read the rows later in the loop #~ print(row) query = 'insert into MyTable({0}) values ({1})' query = query.format(','.join(columns), ','.join('?' * len(columns))) print(query) cursor = con.cursor() for row in reader: cursor.execute(query, row) con.commit() con.close()
You can also do it easy with peewee orm. For this you only use an extension from peewee, the playhouse.csv_loader: from playhouse.csv_loader import * db = SqliteDatabase('city_spec.db') Test = load_csv(db, 'dict_output.csv') You created the database city_spec.db with the headers as fields and the data from the dict_output.csv If you don't have peewee you can install it with pip install peewee
CSV - MYSQL Using Python
After reading several inputs I still can't get this to work. Most likely I'm doing it all wrong but I've tried several different approaches What I'm trying to do is extract data from a CSV and add it into my newly created database/table My csv input look like this NodeName,NeId,Object,Time,Interval,Direction,NeAlias,NeType,Position,AVG,MAX,MIN,percent_0-5,percent_5-10,percent_10-15,percent_15-20,percent_20-25,percent_25-30,percent_30-35,percent_35-40,percent_40-45,percent_45-50,percent_50-55,percent_55-60,percent_60-65,percent_65-70,percent_70-75,percent_75-80,percent_80-85,percent_85-90,percent_90-95,percent_95-100,IdLogNum,FailureDescription X13146PAZ,5002,1/11/100,2016-05-16 00:00:00,24,Near End,GE0097-TN01.1,AMM 20PB,-,69684,217287,772,10563,8055,10644,15147,16821,13610,7658,2943,784,152,20,3,0,0,0,0,0,0,0,0,0,- ... X13146PAZ,5002,1/11/102,2016-05-16 00:00:00,24,Near End,GE0097-TN01.1,AMM 20PB,-,3056,28315,215,86310,90,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,- ... X13146PAZ,5002,1/11/103,2016-05-16 00:00:00,24,Near End,GE0097-TN01.1,AMM 20PB,-,769,7195,11,86400,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,- The mysql table is created but possibly that might be the issue as some ar varchar columns and some are integer columns My server is a Ubuntu if that is of any use My Code # -*- coding: utf-8 -*- #Imports from datetime import date, timedelta import sys import MySQLdb as mdb import csv import os #Vars Yesterday = date.today() - timedelta(1) #Opening document RX_Document = open('./reports/X13146PAZ_TN_WAN_ETH_BAND_RX_' + Yesterday.strftime("%Y%m%d") + "_231500.csv" , 'r') RX_Document_Str = './reports/X13146PAZ_TN_WAN_ETH_BAND_RX_' + Yesterday.strftime("%Y%m%d") + "_231500.csv" csv_data = csv.reader(file(RX_Document_Str)) con = mdb.connect('localhost', 'username', 'password','tn_rx_utilization'); counter = 0 for row in csv_data: if counter == 0: print row continue counter = 1 if counter == 1: cur = con.cursor() cur.execute('INSERT INTO RX_UTIL(NodeName, NeId, Object, Time, Interval1,Direction,NeAlias,NeType,Position,AVG,MAX,MIN,percent_5-10,percent_10-15,percent_15-20,percent_20-25,percent_25-30,percent_30-35,percent_35-40,percent_40-45,percent_45-50,percent_50-55,percent_55-60,percent_60-65,percent_65-70,percent_70-75,percent_75-80,percent_80-85,percent_85-90,percent_90-95,percent_95-100,IdLogNum,FailureDescription)' 'VALUES("%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s")',tuple(row[:34])) con.commit() #cur.execute("SELECT VERSION()") #ver = cur.fetchone() con.commit() con.close()
You should not put the placeholder %s in quotes ": cur.execute('''INSERT INTO RX_UTIL(NodeName, NeId, Object, Time, Interval1,Direction, NeAlias,NeType,Position,AVG,MAX,MIN,"percent_5-10","percent_10-15", "percent_15-20","percent_20-25","percent_25-30","percent_30-35", "percent_35-40","percent_40-45","percent_45-50","percent_50-55", "percent_55-60","percent_60-65","percent_65-70","percent_70-75", "percent_75-80","percent_80-85","percent_85-90","percent_90-95", "percent_95-100",IdLogNum,FailureDescription) VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)''', tuple(row[:33]))
You are missing Percent_0-5 from your Insert Remove the quotes from the %s references, this needs to be in String format, but the underlying data type will be passed. There may be issues with datatype resulting from the csv reader. Have Python eval() the csv data to alter type as an INT. Here is some more information from another post: Read data from csv-file and transform to correct data-type cur.execute('INSERT INTO RX_UTIL(NodeName, NeId, Object, Time, Interval1,Direction,NeAlias,NeType,Position,AVG,MAX,MIN,percent_0-5,percent_5-10,percent_10-15,percent_15-20,percent_20-25,percent_25-30,percent_30-35,percent_35-40,percent_40-45,percent_45-50,percent_50-55,percent_55-60,percent_60-65,percent_65-70,percent_70-75,percent_75-80,percent_80-85,percent_85-90,percent_90-95,percent_95-100,IdLogNum,FailureDescription)' 'VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)',tuple(row[:34]))
Write to CSV from sqlite3 database in python
Ok, So I have a database called cars.db which has a table == inventory, Inventory essentially contains ('Ford', 'Hiluz', 2), ('Ford', 'Tek', 6), ('Ford', 'Outlander', 9), ('Honda', 'Dualis', 3), ('Honday', 'Elantre', 4) I then wrote this which is meant to edit that to the csv, however, I can't seem to work this out, in some cases I get stuff to print but its not right, and when I try and fix that, nothing prints. Any suggestions to get me on track? #write table to csv import sqlite3 import csv with sqlite3.connect("cars.db") as connection: csvWriter = csv.writer(open("output.csv", "w")) c = connection.cursor() rows = c.fetchall() for x in rows: csvWriter.writerows(x)
You should just do: rows = c.fetchall() csvWriter.writerows(rows) If the reason you iterate through the rows is because you wan't to preprocess them before writing them to the file, then use the writerow method: rows = c.fetchall() for row in rows: # do your stuff csvWriter.writerow(row)
In order to put tittles in first row, dictionary approach is suggested for table inventory in cars.db import sqlite3 import csv import os.path BASE_DIR = os.path.dirname(os.path.abspath(__file__)) db_path = os.path.join(BASE_DIR, "cars.db") conn = sqlite3.connect(db_path) c = conn.cursor() c.execute("SELECT rowid, * FROM inventory") columns = [column[0] for column in c.description] results = [] for row in c.fetchall(): results.append(dict(zip(columns, row))) with open("output.csv", "w", newline='') as new_file: fieldnames = columns writer = csv.DictWriter(new_file,fieldnames=fieldnames) writer.writeheader() for line in results: writer.writerow(line) conn.close()
Using Pandas should be more performant and requires less code. You can save the data from a sqlite table to a Pandas DataFrame and then use Pandas to write the CSV file. df = pd.read_sql('SELECT * from cars', conn) df.to_csv('cars.csv') Here's the full code that creates your sqlite table with fake data: import pandas as pd import sqlite3 # create Pandas DataFrame data = [('Toyota', 'Hilux', 2), ('Ford', 'Tek', 6), ('Ford', 'Outlander', 9), ('Honda', 'Dualis', 3), ('Honday', 'Elantre', 4)] df = pd.DataFrame.from_records(data, columns=['make', 'model', 'age']) # establish sqlite connection conn = sqlite3.connect('../tmp/cars.db') c = conn.cursor() # create sqlite table c.execute('''CREATE TABLE cars (make text, model text, age int)''') # add data to sqlite table df.to_sql('cars', conn, if_exists='append', index = False) # write sqlite table out as a CSV file df = pd.read_sql('SELECT * from cars', conn) df.to_csv('../tmp/cars.csv') Here's code to write out all the tables in a sqlite database as CSV files with a single command: for table in c.execute("SELECT name FROM sqlite_master WHERE type='table';").fetchall(): t = table[0] df = pd.read_sql('SELECT * from ' + t, conn) df.to_parquet('../tmp/' + t + '.csv') See here for more info.