exlsql 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- exlsql-0.1.0/PKG-INFO +68 -0
- exlsql-0.1.0/README.md +53 -0
- exlsql-0.1.0/exlsql/__init__.py +1 -0
- exlsql-0.1.0/exlsql/app.py +92 -0
- exlsql-0.1.0/exlsql.egg-info/PKG-INFO +68 -0
- exlsql-0.1.0/exlsql.egg-info/SOURCES.txt +9 -0
- exlsql-0.1.0/exlsql.egg-info/dependency_links.txt +1 -0
- exlsql-0.1.0/exlsql.egg-info/requires.txt +1 -0
- exlsql-0.1.0/exlsql.egg-info/top_level.txt +1 -0
- exlsql-0.1.0/setup.cfg +4 -0
- exlsql-0.1.0/setup.py +13 -0
exlsql-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: exlsql
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: SQL-like queries for Excel files
|
|
5
|
+
Author: royal-egoh
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: pandas
|
|
9
|
+
Dynamic: author
|
|
10
|
+
Dynamic: description
|
|
11
|
+
Dynamic: description-content-type
|
|
12
|
+
Dynamic: requires-dist
|
|
13
|
+
Dynamic: requires-python
|
|
14
|
+
Dynamic: summary
|
|
15
|
+
|
|
16
|
+
# exlsql
|
|
17
|
+
|
|
18
|
+
Query Excel files using SQL syntax. Pass a SQL string and an `.xlsx` file — get a filtered, queried Excel file back.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install exlsql
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from exlsql import Query
|
|
34
|
+
|
|
35
|
+
q = Query("SELECT name, age FROM Sheet1 WHERE age > 30", excel_file="data.xlsx")
|
|
36
|
+
parsed = q.parse()
|
|
37
|
+
output = q.to_excel(parsed)
|
|
38
|
+
|
|
39
|
+
print(output) # data_output.xlsx
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Supported Syntax
|
|
45
|
+
|
|
46
|
+
| Feature | Example |
|
|
47
|
+
|---|---|
|
|
48
|
+
| Select columns | `SELECT name, age FROM Sheet1` |
|
|
49
|
+
| Select all | `SELECT * FROM Sheet1` |
|
|
50
|
+
| Filter rows | `WHERE age > 30` |
|
|
51
|
+
| Multiple conditions | `WHERE age > 30 AND city = 'Lagos'` |
|
|
52
|
+
| Column names with spaces | `SELECT "first name" FROM Sheet1` |
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Notes
|
|
57
|
+
|
|
58
|
+
- `FROM` refers to the **sheet name** inside the Excel file
|
|
59
|
+
- Only `.xlsx` files are supported
|
|
60
|
+
- The output is written to a new file — e.g. `data.xlsx` → `data_output.xlsx`
|
|
61
|
+
- String values in `WHERE` must be wrapped in single quotes: `city = 'New York'`
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Requirements
|
|
66
|
+
|
|
67
|
+
- pandas
|
|
68
|
+
- openpyxl
|
exlsql-0.1.0/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# exlsql
|
|
2
|
+
|
|
3
|
+
Query Excel files using SQL syntax. Pass a SQL string and an `.xlsx` file — get a filtered, queried Excel file back.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install exlsql
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
from exlsql import Query
|
|
19
|
+
|
|
20
|
+
q = Query("SELECT name, age FROM Sheet1 WHERE age > 30", excel_file="data.xlsx")
|
|
21
|
+
parsed = q.parse()
|
|
22
|
+
output = q.to_excel(parsed)
|
|
23
|
+
|
|
24
|
+
print(output) # data_output.xlsx
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Supported Syntax
|
|
30
|
+
|
|
31
|
+
| Feature | Example |
|
|
32
|
+
|---|---|
|
|
33
|
+
| Select columns | `SELECT name, age FROM Sheet1` |
|
|
34
|
+
| Select all | `SELECT * FROM Sheet1` |
|
|
35
|
+
| Filter rows | `WHERE age > 30` |
|
|
36
|
+
| Multiple conditions | `WHERE age > 30 AND city = 'Lagos'` |
|
|
37
|
+
| Column names with spaces | `SELECT "first name" FROM Sheet1` |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Notes
|
|
42
|
+
|
|
43
|
+
- `FROM` refers to the **sheet name** inside the Excel file
|
|
44
|
+
- Only `.xlsx` files are supported
|
|
45
|
+
- The output is written to a new file — e.g. `data.xlsx` → `data_output.xlsx`
|
|
46
|
+
- String values in `WHERE` must be wrapped in single quotes: `city = 'New York'`
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Requirements
|
|
51
|
+
|
|
52
|
+
- pandas
|
|
53
|
+
- openpyxl
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from app import Query
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
import re
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Query:
|
|
7
|
+
def __init__(self, sql, excel_file=None):
|
|
8
|
+
if not excel_file or not excel_file.endswith(".xlsx") :
|
|
9
|
+
raise ValueError("Wrong file type, must be .xlsx")
|
|
10
|
+
self.sql = sql
|
|
11
|
+
self.excel_file = excel_file
|
|
12
|
+
|
|
13
|
+
def parse(self):
|
|
14
|
+
try:
|
|
15
|
+
output = {'select': [], 'from': '', 'where': ''}
|
|
16
|
+
sql_string = self.sql
|
|
17
|
+
# words = sql_string.split()
|
|
18
|
+
words = words = re.findall(r'"[^"]*"|\'[^\']*\'|\S+', sql_string)
|
|
19
|
+
i = 0
|
|
20
|
+
while i < len(words):
|
|
21
|
+
if words[i].upper() == "SELECT":
|
|
22
|
+
i += 1
|
|
23
|
+
if i >= len(words):
|
|
24
|
+
raise ValueError("Invalid SQL: incomplete SELECT clause")
|
|
25
|
+
if words[i] == "FROM":
|
|
26
|
+
output['select'].append("*")
|
|
27
|
+
break
|
|
28
|
+
while i < len(words) and words[i].upper() != "FROM":
|
|
29
|
+
if words[i] == "*":
|
|
30
|
+
output['select'].append(words[i])
|
|
31
|
+
break
|
|
32
|
+
clean_word = words[i].strip(",").strip('"').strip("'")
|
|
33
|
+
output['select'].append(clean_word)
|
|
34
|
+
i += 1
|
|
35
|
+
|
|
36
|
+
elif words[i].upper() == "FROM":
|
|
37
|
+
i += 1
|
|
38
|
+
if i < len(words):
|
|
39
|
+
output['from'] = words[i]
|
|
40
|
+
i += 1
|
|
41
|
+
|
|
42
|
+
elif words[i].upper() == "WHERE":
|
|
43
|
+
i += 1
|
|
44
|
+
condition = []
|
|
45
|
+
while i < len(words):
|
|
46
|
+
if words[i] in ("AND", "OR"):
|
|
47
|
+
output['where'] += ' '.join(condition) + \
|
|
48
|
+
' ' + words[i] + ' '
|
|
49
|
+
condition = []
|
|
50
|
+
else:
|
|
51
|
+
condition.append(words[i])
|
|
52
|
+
i += 1
|
|
53
|
+
if condition:
|
|
54
|
+
output['where'] += ' '.join(condition)
|
|
55
|
+
break
|
|
56
|
+
# elif words[i] == "ORDER":
|
|
57
|
+
# while []
|
|
58
|
+
# i+=1
|
|
59
|
+
|
|
60
|
+
else:
|
|
61
|
+
i += 1
|
|
62
|
+
return output
|
|
63
|
+
except Exception as e:
|
|
64
|
+
raise ValueError(e)
|
|
65
|
+
|
|
66
|
+
# {'select': ['name', 'age'], 'from': 'users', 'where': "age > 30 AND city = 'New York'"}
|
|
67
|
+
def to_excel(self, parsed):
|
|
68
|
+
if not parsed['from']:
|
|
69
|
+
raise ValueError("Invalid sql syntax")
|
|
70
|
+
else:
|
|
71
|
+
file = pd.read_excel(self.excel_file, sheet_name=parsed['from'])
|
|
72
|
+
select_quer = []
|
|
73
|
+
# SELECT QUERY
|
|
74
|
+
if parsed['select'] == ['*'] or not parsed['select']:
|
|
75
|
+
pass
|
|
76
|
+
else:
|
|
77
|
+
for i in parsed['select']:
|
|
78
|
+
select_quer.append(f"{i}")
|
|
79
|
+
file = file[select_quer]
|
|
80
|
+
|
|
81
|
+
# WHERE QUERY
|
|
82
|
+
if parsed['where']:
|
|
83
|
+
parsed['where'] = re.sub(
|
|
84
|
+
r'(?<![<>!])=(?!=)', '==', parsed['where'])
|
|
85
|
+
|
|
86
|
+
file = file.query(parsed['where'])
|
|
87
|
+
# new file
|
|
88
|
+
name, ext = os.path.splitext(self.excel_file)
|
|
89
|
+
output_path = f"{name}_output{ext}"
|
|
90
|
+
file.to_excel(output_path, index=False)
|
|
91
|
+
|
|
92
|
+
return output_path
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: exlsql
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: SQL-like queries for Excel files
|
|
5
|
+
Author: royal-egoh
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: pandas
|
|
9
|
+
Dynamic: author
|
|
10
|
+
Dynamic: description
|
|
11
|
+
Dynamic: description-content-type
|
|
12
|
+
Dynamic: requires-dist
|
|
13
|
+
Dynamic: requires-python
|
|
14
|
+
Dynamic: summary
|
|
15
|
+
|
|
16
|
+
# exlsql
|
|
17
|
+
|
|
18
|
+
Query Excel files using SQL syntax. Pass a SQL string and an `.xlsx` file — get a filtered, queried Excel file back.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install exlsql
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from exlsql import Query
|
|
34
|
+
|
|
35
|
+
q = Query("SELECT name, age FROM Sheet1 WHERE age > 30", excel_file="data.xlsx")
|
|
36
|
+
parsed = q.parse()
|
|
37
|
+
output = q.to_excel(parsed)
|
|
38
|
+
|
|
39
|
+
print(output) # data_output.xlsx
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Supported Syntax
|
|
45
|
+
|
|
46
|
+
| Feature | Example |
|
|
47
|
+
|---|---|
|
|
48
|
+
| Select columns | `SELECT name, age FROM Sheet1` |
|
|
49
|
+
| Select all | `SELECT * FROM Sheet1` |
|
|
50
|
+
| Filter rows | `WHERE age > 30` |
|
|
51
|
+
| Multiple conditions | `WHERE age > 30 AND city = 'Lagos'` |
|
|
52
|
+
| Column names with spaces | `SELECT "first name" FROM Sheet1` |
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Notes
|
|
57
|
+
|
|
58
|
+
- `FROM` refers to the **sheet name** inside the Excel file
|
|
59
|
+
- Only `.xlsx` files are supported
|
|
60
|
+
- The output is written to a new file — e.g. `data.xlsx` → `data_output.xlsx`
|
|
61
|
+
- String values in `WHERE` must be wrapped in single quotes: `city = 'New York'`
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Requirements
|
|
66
|
+
|
|
67
|
+
- pandas
|
|
68
|
+
- openpyxl
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pandas
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
exlsql
|
exlsql-0.1.0/setup.cfg
ADDED
exlsql-0.1.0/setup.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="exlsql",
|
|
5
|
+
version="0.1.0",
|
|
6
|
+
packages=find_packages(),
|
|
7
|
+
install_requires=["pandas"],
|
|
8
|
+
author="royal-egoh",
|
|
9
|
+
description="SQL-like queries for Excel files",
|
|
10
|
+
long_description=open("README.md").read(),
|
|
11
|
+
long_description_content_type="text/markdown",
|
|
12
|
+
python_requires=">=3.8",
|
|
13
|
+
)
|