Konvertovanje SQL tabele u Excell fajl [ Python ]

Baby Yoda

Contributor
Poruka
21.755
Napisao sam ovu skriptu pre dva meseca i nalazi se na git-u (logično). Za rad vam treba openpyxl. Samo roknete:
Python:
pip install openpyxl

U principu, odaberete neku tabelu iz baze (u kodu morate reći koju) i pokrenete skriptu. Nije rađen GUI za ovu skriptu, ali imam i sa interfejsom.

Python:
'''
    Author: Aleksandar Arsic
    Contact email: srpskaitucionica@gmail.com
    Github: https://github.com/SrpskaITucionica
'''


from openpyxl import Workbook
import sqlite3

'''
    This part of code converts SQL table into Excel file.
    Database name, table name and excel file name are generic.
    DB should be in the same folder as main.py module, or any module that runs this code
'''

###################### WORKING WITH SQL PART ######################

con = sqlite3.connect('database_name.db')
cursor = con.cursor()

get_data_from_table_sql = "SELECT * FROM table_name"
cursor.execute(get_data_from_table_sql)
# GET TABLE DATA
rows = cursor.fetchall()

# GET COLUMN NAMES
cursor2 = con.execute('SELECT * FROM table_name')
names = list(map(lambda x: x[0], cursor.description))

###################### WORKING WITH EXCEL PART ######################

wb = Workbook()
ws = wb.active
ws.title = 'Worksheet name'

ws.append(names)
for row in rows:
    ws.append(list(row))

wb.save('excel_file_name.xlsx')
 
Evo ga moj davni program da se iz fajlova prebaci u xlsx, sa sve C vraperom (xlsxwriter) u Rustu :
Kod:
use std::ffi::{CString, CStr};
#[repr(C)]
struct lxw_workbook(*mut lxw_workbook);
#[repr(C)]
struct lxw_worksheet(*mut lxw_worksheet);
#[repr(C)]
#[derive(Clone)]
struct lxw_format(*mut lxw_format);
#[link(name="xlsxwriter",kind="dylib")]
extern "C" {
    fn workbook_new(wkbk: *const i8)->*mut lxw_workbook;
    fn workbook_add_worksheet(wkbk:*mut lxw_workbook, sheetname:*const i8)->*mut lxw_worksheet;
    fn workbook_add_format(wkbk:*mut lxw_workbook)->*mut lxw_format;
    fn workbook_close(wkbk:*mut lxw_workbook)->i32;
    fn lxw_strerror(errnum:i32)->*const i8;
    fn format_set_bg_color(fmt:*mut lxw_format, color: u32);
    fn worksheet_write_string(wksht:*mut lxw_worksheet, row:u32,col:u16,s:*const i8,fmt:*const lxw_format)->i32;
}
impl lxw_workbook {
    fn new(wkbk:&str)->lxw_workbook {
        unsafe {lxw_workbook(workbook_new(CString::new(wkbk).unwrap().as_ptr())) }
    }
    fn add_worksheet(&self,sheetname:&str)->lxw_worksheet {
        unsafe {lxw_worksheet(workbook_add_worksheet(self.0,CString::new(sheetname).unwrap().as_ptr())) }
    }
    fn add_format(&self)->lxw_format {
        unsafe {lxw_format(workbook_add_format(self.0)) }
    }
    fn close(&self)->i32{
        unsafe {workbook_close(self.0)}
    }
    fn strerror(errnum:i32)->&'static str {
        unsafe { CStr::from_ptr(lxw_strerror(errnum)).to_str().unwrap() }
    }
}
impl Drop for lxw_workbook {
    fn drop(&mut self) {
        let rc = self.close();
        if rc != 0 {
            panic!("{}",lxw_workbook::strerror(rc));
        }
    }
}
impl lxw_format {
    fn set_bg_color(&self, color: u32){
        unsafe { format_set_bg_color(self.0,color); }
    }
}
impl lxw_worksheet {
    fn write_string(&self, row:u32, col:u16, s:&str,fmt:lxw_format)->Result<(),String>{
        let s = CString::new(s);
        let rc;
        unsafe { rc = worksheet_write_string(self.0,row,col,s.unwrap().as_ptr(),fmt.0);}
        if rc == 0 {
            Ok(())
        }else {
            Err(lxw_workbook::strerror(rc).to_string())
        }
    }
}

use std::io;
use std::fs::File;
use std::fs::read_dir;
use std::io::prelude::*;
use std::collections::BTreeMap;
type map_t = BTreeMap<i32,i32>;
fn main()->io::Result<()>{
    let mut common:BTreeMap<String,Vec<(char,map_t)>> = BTreeMap::new();
    let mut buf = String::new();
    if let Ok(dir) = read_dir("BabyNames") {
        for file in dir {
            let file = file?;
            let mut f = File::open(file.path())?;
            let path = file.path();
            let fname = path.to_str().unwrap().to_string();
            let it = fname.split('_').collect::<Vec<_>>();
            let it1 = it[0].split('/').collect::<Vec<_>>();
            let year = it1[1].parse::<i32>().unwrap();
            let c = if it[1] == "GirlsNames.txt" {
                'F'
            } else {
                'M'
            };
            buf.clear();
            let _ = f.read_to_string(&mut buf);
            for line in buf.lines() {
                let two:Vec<_> = line.split_whitespace().collect();
                let r = common.entry(two[0].to_string()).or_insert(vec!{(c,map_t::new())});
                (*r).last_mut().unwrap().1.insert(year,two[1].parse::<i32>().unwrap());
            }
        }
    } else {
        println!("Not in directory above BabyNames...");
    }
    let wkbk = lxw_workbook::new("example.xlsx");
    let wksht = wkbk.add_worksheet("Names");
    let hc = wkbk.add_format();
    hc.set_bg_color(0xe0e0e0);
    let gc = wkbk.add_format();
    gc.set_bg_color(0xf9c7ff);
    let bc = wkbk.add_format();
    bc.set_bg_color(0xb8bbff);
    let mut years = BTreeMap::new();
    for (i,j) in (1900..=2012).rev().enumerate() {
        years.insert(j,i);
        let _ = wksht.write_string(0,i as u16+2,j.to_string().as_str(),hc.clone());
    }
    let _ = wksht.write_string(0,0, "Name",hc.clone());
    let _ = wksht.write_string(0,1, "Gender",hc.clone());
    for (ord,(name,pair)) in common.iter().enumerate() {
        for (gender,map) in pair.iter() {
            for (year,value) in map.iter().rev() {
                let clr;
                if *gender == 'F' {
                    clr = gc.clone();
                    let _ = wksht.write_string(ord as u32+1,0,name,gc.clone());
                    let _ = wksht.write_string(ord as u32+1,1,"F",gc.clone());
                } else {
                    clr = bc.clone();
                    let _ = wksht.write_string(ord as u32+1,0,name,bc.clone());
                    let _ = wksht.write_string(ord as u32+1,1,"M",bc.clone());
                }
                let _ = wksht.write_string(ord as u32+1,years[&*year]as u16+2,value.to_string().as_str(),clr);
            }
        }
    }
    Ok(())
}
 
Napisao sam ovu skriptu pre dva meseca i nalazi se na git-u (logično). Za rad vam treba openpyxl. Samo roknete:
Python:
pip install openpyxl

U principu, odaberete neku tabelu iz baze (u kodu morate reći koju) i pokrenete skriptu. Nije rađen GUI za ovu skriptu, ali imam i sa interfejsom.

Python:
'''
    Author: Aleksandar Arsic
    Contact email: srpskaitucionica@gmail.com
    Github: https://github.com/SrpskaITucionica
'''


from openpyxl import Workbook
import sqlite3

'''
    This part of code converts SQL table into Excel file.
    Database name, table name and excel file name are generic.
    DB should be in the same folder as main.py module, or any module that runs this code
'''

###################### WORKING WITH SQL PART ######################

con = sqlite3.connect('database_name.db')
cursor = con.cursor()

get_data_from_table_sql = "SELECT * FROM table_name"
cursor.execute(get_data_from_table_sql)
# GET TABLE DATA
rows = cursor.fetchall()

# GET COLUMN NAMES
cursor2 = con.execute('SELECT * FROM table_name')
names = list(map(lambda x: x[0], cursor.description))

###################### WORKING WITH EXCEL PART ######################

wb = Workbook()
ws = wb.active
ws.title = 'Worksheet name'

ws.append(names)
for row in rows:
    ws.append(list(row))

wb.save('excel_file_name.xlsx')
Може ли објашњење шта је гит?
 
Може ли објашњење шта је гит?
GitHub je mesto gde programeri mogu kačiti svoj kod (dele sa drugima), rade zajedno na projektima.
Tipa, radi se neki globalni projekat gde svako može da da svoj doprines ukoliko ima te privilegije. Tu nastupa sistem verzionisanja.

Recimo, glavni projekat je jedna vertikalna linija, ali, ako ja treba da dodam neku stvar, neću je menjati direktno na projektu jer drugi isto žele da rade na tom projektu. Ne možemo se mešati. Zato ja napravim novu granu gde imam celu kopiju glavnog projekta. Radim na svom kompu izmene i one se ne vide na glavnom projektu. Kada sam završio, ja vršim spajanje sa glavnom (master) granom gde moje izmene postaju deo glavne aplikacije. Ostali programeri moraju sada povući te izmene na njihove grane kako bi imali kompletnu verziju, da ne dođe do konflikta u fajlovima.
 
Може ли објашњење шта је гит?
Git je platforma za kontrolu versionisanja (tzv. versioning control).
Git je, de facto, standard koji gotovo svi progameri koriste za skladistenje svog koda, za pracenje toka razvoja koda (svako dodavanje nekog parceta koda se belezi i moze se pratiti ko je kada sta dodao), i mnogo pomaze u samoj organizaciji kada vise ljudi radi na jednom projektu (zato je i davnih dana osmisljen od strane Linus Torvaldsa - kreatora linuxa).

Github je cloud platforma koja radi na principu git-a.
 
Poslednja izmena:
Git je platforma za kontrolu versionisanja (tzv. versioning control).
Git je, de facto, standard koji gotovo svi progameri koriste za skladistenje svog koda, za pracenje toka razvoja koda (svako dodavanje nekog parceta koda se belezi i moze se pratiti ko je kada sta dodao), i mnogo pomaze u samoj organizaciji kada vise ljudi radi na jednom projektu (zato je i davnih dana osmisljen od strane Linus Torvaldsa - kreatora linuxa).

Github je cloud platforma koja radi na principu git-a.
Linus nije bio zadovoljan ostalim versioning sistemima, pa je krenuo da piše git, koji eto posta najpopularniji...
 
Evo ga moj davni program da se iz fajlova prebaci u xlsx, sa sve C vraperom (xlsxwriter) u Rustu :
Kod:
use std::ffi::{CString, CStr};
#[repr(C)]
struct lxw_workbook(*mut lxw_workbook);
#[repr(C)]
struct lxw_worksheet(*mut lxw_worksheet);
#[repr(C)]
#[derive(Clone)]
struct lxw_format(*mut lxw_format);
#[link(name="xlsxwriter",kind="dylib")]
extern "C" {
    fn workbook_new(wkbk: *const i8)->*mut lxw_workbook;
    fn workbook_add_worksheet(wkbk:*mut lxw_workbook, sheetname:*const i8)->*mut lxw_worksheet;
    fn workbook_add_format(wkbk:*mut lxw_workbook)->*mut lxw_format;
    fn workbook_close(wkbk:*mut lxw_workbook)->i32;
    fn lxw_strerror(errnum:i32)->*const i8;
    fn format_set_bg_color(fmt:*mut lxw_format, color: u32);
    fn worksheet_write_string(wksht:*mut lxw_worksheet, row:u32,col:u16,s:*const i8,fmt:*const lxw_format)->i32;
}
impl lxw_workbook {
    fn new(wkbk:&str)->lxw_workbook {
        unsafe {lxw_workbook(workbook_new(CString::new(wkbk).unwrap().as_ptr())) }
    }
    fn add_worksheet(&self,sheetname:&str)->lxw_worksheet {
        unsafe {lxw_worksheet(workbook_add_worksheet(self.0,CString::new(sheetname).unwrap().as_ptr())) }
    }
    fn add_format(&self)->lxw_format {
        unsafe {lxw_format(workbook_add_format(self.0)) }
    }
    fn close(&self)->i32{
        unsafe {workbook_close(self.0)}
    }
    fn strerror(errnum:i32)->&'static str {
        unsafe { CStr::from_ptr(lxw_strerror(errnum)).to_str().unwrap() }
    }
}
impl Drop for lxw_workbook {
    fn drop(&mut self) {
        let rc = self.close();
        if rc != 0 {
            panic!("{}",lxw_workbook::strerror(rc));
        }
    }
}
impl lxw_format {
    fn set_bg_color(&self, color: u32){
        unsafe { format_set_bg_color(self.0,color); }
    }
}
impl lxw_worksheet {
    fn write_string(&self, row:u32, col:u16, s:&str,fmt:lxw_format)->Result<(),String>{
        let s = CString::new(s);
        let rc;
        unsafe { rc = worksheet_write_string(self.0,row,col,s.unwrap().as_ptr(),fmt.0);}
        if rc == 0 {
            Ok(())
        }else {
            Err(lxw_workbook::strerror(rc).to_string())
        }
    }
}

use std::io;
use std::fs::File;
use std::fs::read_dir;
use std::io::prelude::*;
use std::collections::BTreeMap;
type map_t = BTreeMap<i32,i32>;
fn main()->io::Result<()>{
    let mut common:BTreeMap<String,Vec<(char,map_t)>> = BTreeMap::new();
    let mut buf = String::new();
    if let Ok(dir) = read_dir("BabyNames") {
        for file in dir {
            let file = file?;
            let mut f = File::open(file.path())?;
            let path = file.path();
            let fname = path.to_str().unwrap().to_string();
            let it = fname.split('_').collect::<Vec<_>>();
            let it1 = it[0].split('/').collect::<Vec<_>>();
            let year = it1[1].parse::<i32>().unwrap();
            let c = if it[1] == "GirlsNames.txt" {
                'F'
            } else {
                'M'
            };
            buf.clear();
            let _ = f.read_to_string(&mut buf);
            for line in buf.lines() {
                let two:Vec<_> = line.split_whitespace().collect();
                let r = common.entry(two[0].to_string()).or_insert(vec!{(c,map_t::new())});
                (*r).last_mut().unwrap().1.insert(year,two[1].parse::<i32>().unwrap());
            }
        }
    } else {
        println!("Not in directory above BabyNames...");
    }
    let wkbk = lxw_workbook::new("example.xlsx");
    let wksht = wkbk.add_worksheet("Names");
    let hc = wkbk.add_format();
    hc.set_bg_color(0xe0e0e0);
    let gc = wkbk.add_format();
    gc.set_bg_color(0xf9c7ff);
    let bc = wkbk.add_format();
    bc.set_bg_color(0xb8bbff);
    let mut years = BTreeMap::new();
    for (i,j) in (1900..=2012).rev().enumerate() {
        years.insert(j,i);
        let _ = wksht.write_string(0,i as u16+2,j.to_string().as_str(),hc.clone());
    }
    let _ = wksht.write_string(0,0, "Name",hc.clone());
    let _ = wksht.write_string(0,1, "Gender",hc.clone());
    for (ord,(name,pair)) in common.iter().enumerate() {
        for (gender,map) in pair.iter() {
            for (year,value) in map.iter().rev() {
                let clr;
                if *gender == 'F' {
                    clr = gc.clone();
                    let _ = wksht.write_string(ord as u32+1,0,name,gc.clone());
                    let _ = wksht.write_string(ord as u32+1,1,"F",gc.clone());
                } else {
                    clr = bc.clone();
                    let _ = wksht.write_string(ord as u32+1,0,name,bc.clone());
                    let _ = wksht.write_string(ord as u32+1,1,"M",bc.clone());
                }
                let _ = wksht.write_string(ord as u32+1,years[&*year]as u16+2,value.to_string().as_str(),clr);
            }
        }
    }
    Ok(())
}
Nisam znao da si na Rust u
Kakvo je iskustvo?
 
Nisam znao da si na Rust u
Kakvo je iskustvo?
Rust se dosta menjao, sa GC-a su prešli na C++ stil, sa više vrsta pointera na dva, sad je stabilan, u vreme dok nije bio stabilan sabmitovao
sam patcheve za kompajler i tako ČP
Jezik koji mi je interesantniji od C++ zbog toga što su očigledno hteli da srede probleme koje ima C++, ali nažalost ima samo jedan kompajler
koliko znam, dok MS Intel i još neki ne naprave kompajler, teško će to da zaživi. Sada može u njemu fino da se radi, ali teško da će zameniti
C++...
 
Panda biblioteka za python već imam rutine za čitanje iz sql i upis u Excel file, tako da ukoliko nema potrebe za nekim dodatnim uređivanjem excel fila mislim da je to najjednostavnije npr.

import pandas as pd
# create connection to db
conn = sqlite3.connect('database_name.db')
# read from db
table_name = "test"
df = pd.read_sql_query(f"SELECT * from {table_name}", con)
#close the connection
con.close()
# export to excel
df.to_excel (r'C:\Users\Jpeca\Desktop\excel_file_name.xlsx', index = False, header=True)
 
Ne znam sta ti je to.
ti i ja radimo na istom programu. Obojca gadjamo github da razmenimo nase updates. GitHub je centralni repo.

Mantra je:
- pull / merge (zavisno od stila)
- code
- commit and push

Sistem za razmenu je centralizovan.

Kod Hg nije... ne postoji centralni repo za razmenu.

---
Zaboravih
bolja matra je
pull/merge
push (be polite)
code
commit/push
 
ti i ja radimo na istom programu. Obojca gadjamo github da razmenimo nase updates. GitHub je centralni repo.

Mantra je:
- pull / merge (zavisno od stila)
- code
- commit and push

Sistem za razmenu je centralizovan.

Kod Hg nije... ne postoji centralni repo za razmenu.
Pa ne mora tako na git. Mozes na bilo koji repo. To sto se gura recimo gerrit kao code review sistem, nije obaveza...
 
Sad ja tebe ne razumem.
Push fetch moze sa bilo kog remote repoa.
gerrit? nisam sa time radio ... valja li ?
pa ne znam moras da instaliras hookove da doda one id-jeve u svaki commit.
U principu kad nesto podje naopako moras da ga zaobidjes sa force push.
Dakle kada se radi sa granama malo je nezgodno kada mora da se mergeuje.
 
Push fetch moze sa bilo kog remote repoa.
A to ... da moze na vise repo-a, ali su svaki je centralni.
Mozda je problem sa izrazavanjem - kad kazem 'centralni' mislim da postoji server (ili vise njih ako hoces backup ili specijalnu namenu) ali ima server - tu je sustinska razlika u smislu 'centralni'. Decentralizovan misli se da ne postoji taj server, ili ni jedan od njih.

pa ne znam moras da instaliras hookove da doda one id-jeve u svaki commit.
U principu kad nesto podje naopako moras da ga zaobidjes sa force push.
Dakle kada se radi sa granama malo je nezgodno kada mora da se mergeuje.
code revision, ako je praksa, da, prilicno komplikuje stvari, znam da smo se mi (ekipa sa kojom sam radio pre par godina), prilicno cesali oko glave kako da push, a da ne push. Drugim recima kako da se ne komituje na server, a da ipak moze da se radi code review. Doduse, to je mozda bilo tada sa tim alatom koji smo mi koristili. Mozda je to sad neko shvatio i popravio flow.

E sad... meni je lakse sa branchevima, ali to je vec ko sto rekoh stvar stila (a i potrebe, i organizacije tima).
Ali sigurno cu pogledati taj software, mozda ga primenim ako je reasonable.
 
A to ... da moze na vise repo-a, ali su svaki je centralni.
Mozda je problem sa izrazavanjem - kad kazem 'centralni' mislim da postoji server (ili vise njih ako hoces backup ili specijalnu namenu) ali ima server - tu je sustinska razlika u smislu 'centralni'. Decentralizovan misli se da ne postoji taj server, ili ni jedan od njih.
Pa ne znam na sta mislis kada kazes decentralizovan? Mozda fragmentizovan na vise servera? To git ne moze...
E sad... meni je lakse sa branchevima, ali to je vec ko sto rekoh stvar stila (a i potrebe, i organizacije tima).
Ali sigurno cu pogledati taj software, mozda ga primenim ako je reasonable.
Ovo radi dobro ne mergeuje na glavnu granu dok se ne odobri. Problemi nastaju ako se nesto abandonuje ili odbije review, moras
da pazis kako sa lokalnim repoom.
 
Pa ne znam na sta mislis kada kazes decentralizovan? Mozda fragmentizovan na vise servera? To git ne moze...

https://www.mercurial-scm.org/wiki/UnderstandingMercurial

Ovo radi dobro ne mergeuje na glavnu granu dok se ne odobri.
To mi je dovoljno.

Problemi nastaju ako se nesto abandonuje ili odbije review, moras
da pazis kako sa lokalnim repoom.
Aha, ako sam dobro shvatio, ako promene nisu approved nego ide nazad na development. Onda sta? Moras da se reversujes commit (vratis neki commit unazad?) a hoces da zadrzis promene... mada onda mozes i da branchujes feature, pa da se vratis. U svakom slucaju verovatno je malo glavolomka dok se ne otkrije mantra. :)
 
Niko te ne sprecava da tako radis sa gitom, ali ljudi su navikli na centralne repozitorijume...
To mi je dovoljno.


Aha, ako sam dobro shvatio, ako promene nisu approved nego ide nazad na development. Onda sta? Moras da se reversujes commit (vratis neki commit unazad?) a hoces da zadrzis promene... mada onda mozes i da branchujes feature, pa da se vratis. U svakom slucaju verovatno je malo glavolomka dok se ne otkrije mantra. :)
Pa da, imas jednu sliku u lokalnom repou, a drugu na remote. Osim toga verovatno neces da odustanes od svojih izmena, pa pushujesh ponovo :P
 

Back
Top