Skip to content

Commit 508ac88

Browse files
committed
functions descriptions and windows authentication added
1 parent c6c9c2a commit 508ac88

5 files changed

Lines changed: 236 additions & 87 deletions

File tree

README.md

Lines changed: 91 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
![Python](https://img.shields.io/badge/Python-3.6%2B-blue.svg) ![SQL Server](https://img.shields.io/badge/SQL%20Server-ODBC%20Driver%2017-red.svg) ![MIT License](https://img.shields.io/badge/License-MIT-green.svg)
44

5-
Welcome to **PyDBManager** – a Python package for managing **SQL Server connections and queries** easily and efficiently! 🎯
5+
Welcome to **PyDBManager** – a Python package for managing **SQL Server connections and queries** easily and efficiently! 🌟
66

77
This guide will help you:
88
- ✅ Install PyDBManager
9-
- ✅ Set up your `.env` file for credentials
9+
- ✅ Set up your `.env` file for SQL or Windows Authentication
1010
- ✅ Perform SQL operations using Python
11-
-Save query results
12-
-Use caching & batch fetching
11+
-Create tables, insert, update, and bulk load DataFrames
12+
-Save query results and use batch fetching
1313

1414
---
1515

@@ -28,15 +28,20 @@ To avoid hardcoding credentials, create a `.env` file in your project directory.
2828
### **Steps**
2929
1. **Create a `.env` file** in your project root.
3030
2. **Add the following credentials** (update as needed):
31-
```
31+
```env
3232
DB_SERVER=localhost
3333
DB_DATABASE=your_database_name
34+
DB_DRIVER=ODBC Driver 17 for SQL Server
35+
36+
# For SQL Authentication
3437
DB_USERNAME=your_username
3538
DB_PASSWORD=your_password
36-
DB_DRIVER={ODBC Driver 17 for SQL Server}
39+
DB_AUTH_MODE=sql
40+
41+
# For Windows Authentication
42+
# DB_AUTH_MODE=windows
3743
```
3844
3. **Ensure `.env` is ignored by Git** (Add `.env` to `.gitignore`).
39-
4. **Verify that `.env` loads correctly** (Next step).
4045
4146
---
4247
@@ -53,23 +58,15 @@ load_dotenv()
5358
print("\u2705 Database Configuration Loaded:")
5459
print(f"SERVER: {os.getenv('DB_SERVER')}")
5560
print(f"DATABASE: {os.getenv('DB_DATABASE')}")
61+
print(f"AUTH MODE: {os.getenv('DB_AUTH_MODE')}")
5662
print(f"USERNAME: {os.getenv('DB_USERNAME')}")
5763
print(f"PASSWORD: {'*' * len(os.getenv('DB_PASSWORD')) if os.getenv('DB_PASSWORD') else 'Not Set'}")
5864
print(f"DRIVER: {os.getenv('DB_DRIVER')}")
5965
```
60-
**Expected Output**
61-
```
62-
Database Configuration Loaded:
63-
SERVER: localhost
64-
DATABASE: testDB
65-
USERNAME: your_username
66-
PASSWORD: **********
67-
DRIVER: {ODBC Driver 17 for SQL Server}
68-
```
6966

7067
---
7168

72-
## **4. Connect to the Database**
69+
## **4. Connect to the Database (SQL or Windows Authentication)**
7370
```python
7471
from pydbmanager.connection import DatabaseConnection
7572

@@ -83,91 +80,122 @@ if conn:
8380
else:
8481
print("\u274c Connection Failed!")
8582
```
86-
**Expected Output**
87-
```
88-
Connection Successful!
89-
```
9083

9184
---
9285

9386
## **5. Perform SQL Operations**
9487

95-
### **🔹 Fetch All Users**
88+
### 🔹 **Query Data as DataFrame**
9689
```python
9790
from pydbmanager.operations import DatabaseOperations
9891

9992
db_ops = DatabaseOperations()
100-
101-
# Fetch all users
10293
df = db_ops.query_data("SELECT * FROM users", batch_size=5)
103-
df
94+
print(df)
10495
```
105-
**Expected Output** → A **pandas DataFrame** displaying user data.
106-
107-
---
10896

109-
### **🔹 Insert a New Record**
97+
### 🔹 **Insert a New Record**
11098
```python
11199
insert_query = """
112100
INSERT INTO users (name, email, age, gender, phone_number, address, city, country)
113101
VALUES ('John Doe', 'john.doe@example.com', 29, 'Male', '123-456-7890', '123 Elm St', 'New York', 'USA')
114102
"""
115103
db_ops.execute_query(insert_query)
116-
print("\u2705 User inserted successfully!")
117104
```
118105

119-
---
120-
121-
### **🔹 Update a Record**
106+
### 🔹 **Update a Record**
122107
```python
123108
update_query = """
124109
UPDATE users SET age = 30 WHERE email = 'john.doe@example.com'
125110
"""
126111
db_ops.execute_query(update_query)
127-
print("\u2705 User updated successfully!")
128112
```
129113

130-
---
131-
132-
### **🔹 Delete a Record**
114+
### 🔹 **Delete a Record**
133115
```python
134116
delete_query = """
135117
DELETE FROM users WHERE email = 'john.doe@example.com'
136118
"""
137119
db_ops.execute_query(delete_query)
138-
print("\u2705 User deleted successfully!")
139120
```
140121

141-
---
142-
143-
## **6. Saving Query Results**
122+
### 🔹 **Create Table**
123+
```python
124+
create_table_sql = """
125+
IF NOT EXISTS (
126+
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'users'
127+
)
128+
BEGIN
129+
CREATE TABLE users (
130+
id INT IDENTITY(1,1) PRIMARY KEY,
131+
name VARCHAR(100),
132+
email VARCHAR(100),
133+
age INT,
134+
gender VARCHAR(10),
135+
phone_number VARCHAR(20),
136+
address VARCHAR(255),
137+
city VARCHAR(100),
138+
country VARCHAR(100)
139+
);
140+
END
141+
"""
142+
db_ops.create_table(create_table_sql)
143+
```
144144

145-
### **🔹 Save Data to CSV**
145+
### 🔹 **Insert a DataFrame to SQL**
146146
```python
147-
db_ops.save_results(df, "users_data.csv", "csv")
148-
print("\u2705 Data saved to users_data.csv")
147+
import pandas as pd
148+
149+
# Example DataFrame
150+
df_users = pd.DataFrame([
151+
{
152+
'name': 'Jane Smith',
153+
'email': 'jane.smith@example.com',
154+
'age': 32,
155+
'gender': 'Female',
156+
'phone_number': '555-555-5555',
157+
'address': '456 Oak Ave',
158+
'city': 'Chicago',
159+
'country': 'USA'
160+
}
161+
])
162+
163+
db_ops.insert_dataframe(df_users, 'users')
149164
```
150-
📁 **Check your project folder for `users_data.csv`**
151165

152-
---
166+
### 🔹 **Update SQL Table with DataFrame**
167+
168+
> **Note:** `key_columns` should include the column(s) used to uniquely identify each row (like `id` or `email`). These are used in the SQL `WHERE` clause to apply updates only to matching rows.
153169
154-
## **7. Using Caching & Batch Fetching**
155170

156-
### **🔹 Query with Caching**
157171
```python
158-
df_cached = db_ops.cached_query("SELECT * FROM users")
159-
df_cached
172+
# Assume df_users contains updated user data
173+
# Example update: change age for a known email
174+
175+
df_users_update = pd.DataFrame([
176+
{
177+
'email': 'jane.smith@example.com',
178+
'age': 33 # updated age
179+
}
180+
])
181+
182+
db_ops.update_table_with_dataframe(df_users_update, 'users', key_columns=['email'])
183+
160184
```
185+
---
186+
187+
## **6. Save Query Results to File**
161188

162-
### **🔹 Query with Batch Fetching**
163189
```python
164-
df_batch = db_ops.query_data("SELECT * FROM users", batch_size= 10)
165-
df_batch
190+
# Save to CSV
191+
results_df.to_csv("output.csv", index=False)
192+
print("\u2705 Data saved to output.csv")
166193
```
167194

168195
---
169196

170-
### **🔹 Closing Connection**
197+
## **7. Closing the Connection**
198+
171199
```python
172200
db_ops.close()
173201
print("\u2705 Database connection closed.")
@@ -176,19 +204,18 @@ print("\u2705 Database connection closed.")
176204
---
177205

178206
## **✅ Congratulations! 🎉**
179-
You’ve successfully used **PyDBManager** for:
180-
- Connecting to SQL Server
181-
- Running SQL queries in Python
182-
- Fetching, inserting, updating & deleting data
183-
- Using caching & batch fetching
184-
- Saving results to a file
207+
You’ve successfully used **PyDBManager** to:
208+
- Connect to SQL Server using SQL or Windows authentication
209+
- Run queries and commands
210+
- Work with DataFrames and tables
211+
- Create, update, and insert into SQL Server tables
212+
- Save data to files and close connections cleanly
185213

186214
---
187215

188-
## **🚀 Contributing & License**
189-
I welcome contributions! Feel free to submit issues and pull requests. 🛠️
216+
## **Contributing & License**
217+
I welcome contributions! Feel free to submit issues and pull requests. 💪
190218

191219
This project is **MIT Licensed** — you are free to modify and distribute it as needed. 🏆
192220

193-
🔥 **Happy Coding!** 🚀
194-
221+
🔥 **Happy Coding!**

pydbmanager/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class Config:
1212
USERNAME = os.getenv("DB_USERNAME")
1313
PASSWORD = os.getenv("DB_PASSWORD")
1414
DRIVER = os.getenv("DB_DRIVER", "{ODBC Driver 17 for SQL Server}")
15+
AUTH_MODE = os.getenv("DB_AUTH_MODE", "sql").strip() # default to sql
1516

1617
@staticmethod
1718
def validate():

pydbmanager/connection.py

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,24 @@ def __init__(self):
1313
self.conn = None
1414

1515
def create_connection(self):
16-
"""Establishes a new database connection using pyodbc."""
17-
connection_string = (
18-
f"DRIVER={Config.DRIVER};"
19-
f"SERVER={Config.SERVER};"
20-
f"DATABASE={Config.DATABASE};"
21-
f"UID={Config.USERNAME};"
22-
f"PWD={Config.PASSWORD};"
23-
"TrustServerCertificate=yes;"
24-
)
16+
if Config.AUTH_MODE.lower() == "windows":
17+
connection_string = (
18+
f"DRIVER={Config.DRIVER};"
19+
f"SERVER={Config.SERVER};"
20+
f"DATABASE={Config.DATABASE};"
21+
"Trusted_Connection=yes;"
22+
"TrustServerCertificate=yes;"
23+
)
24+
else: # SQL Server Authentication
25+
connection_string = (
26+
f"DRIVER={Config.DRIVER};"
27+
f"SERVER={Config.SERVER};"
28+
f"DATABASE={Config.DATABASE};"
29+
f"UID={Config.USERNAME};"
30+
f"PWD={Config.PASSWORD};"
31+
"TrustServerCertificate=yes;"
32+
)
33+
2534
try:
2635
self.conn = pyodbc.connect(connection_string)
2736
logging.info("Database connection established successfully.")
@@ -30,18 +39,29 @@ def create_connection(self):
3039
logging.error(f"Database connection failed: {e}")
3140
return None
3241

42+
3343
def get_connection_string(self):
34-
"""Returns the connection string encoded for use with SQLAlchemy."""
35-
connection_string = (
36-
f"DRIVER={Config.DRIVER};"
37-
f"SERVER={Config.SERVER};"
38-
f"DATABASE={Config.DATABASE};"
39-
f"UID={Config.USERNAME};"
40-
f"PWD={Config.PASSWORD};"
41-
"TrustServerCertificate=yes;"
42-
)
43-
print("🔍 DEBUG CONNECTION STRING (RAW):", connection_string)
44-
return urllib.parse.quote_plus(connection_string)
44+
45+
if Config.AUTH_MODE.lower() == "windows":
46+
conn_str = (
47+
f"DRIVER={Config.DRIVER};"
48+
f"SERVER={Config.SERVER};"
49+
f"DATABASE={Config.DATABASE};"
50+
"Trusted_Connection=yes;"
51+
"TrustServerCertificate=yes;"
52+
)
53+
else:
54+
conn_str = (
55+
f"DRIVER={Config.DRIVER};"
56+
f"SERVER={Config.SERVER};"
57+
f"DATABASE={Config.DATABASE};"
58+
f"UID={Config.USERNAME};"
59+
f"PWD={Config.PASSWORD};"
60+
"TrustServerCertificate=yes;"
61+
)
62+
63+
return urllib.parse.quote_plus(conn_str)
64+
4565

4666
def check_connection(self):
4767
"""Ensures the database connection is active, reconnecting if necessary"""

0 commit comments

Comments
 (0)