Skip to content

Commit

Permalink
Feat: update readme.md (#3)
Browse files Browse the repository at this point in the history
update readme.md
  • Loading branch information
idatsy authored Sep 17, 2024
1 parent 1d4bd11 commit 0f69b2b
Showing 1 changed file with 123 additions and 61 deletions.
184 changes: 123 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,106 +1,168 @@
# QuestDB Python Client
# QuestDB Python Library

This is an open-source Python library for interacting with QuestDB, a high-performance, open-source SQL database designed to process time series data. This client provides an easy-to-use interface for querying and writing data to QuestDB from Python applications.
A robust, strongly-typed Python library for interacting with QuestDB, providing an easy-to-use interface for querying, writing data, and managing logs.

## Features

- Asynchronous and synchronous query execution
- Write single or multiple messages to QuestDB
- Buffer writes for improved performance
- Convert query results to Pandas DataFrames
- Type conversion and parsing of query results
- Support for both HTTP and TCP interfaces
- Asynchronous and synchronous query support
- Strongly-typed data structures
- Easy data insertion with automatic flushing
- Pandas DataFrame integration
- Built-in logging handler for QuestDB
- Comprehensive test coverage

## Installation

You can install the QuestDB Python Client using pip:
Install the QuestDB Python library using pip:

```bash
pip install py-questdb
```

## Quick Start

Here's a simple example to get you started:

```python
import asyncio
from questdb_python_client import QuestDB

async def main():
# Connect to QuestDB
db = QuestDB(host="localhost", port=9000)
from py_questdb import QuestDB

# Write some data
await db.write(
table_name="sensors",
symbols={"location": "room1"},
columns={"temperature": 22.5, "humidity": 60},
at=datetime.now()
)
# Initialize QuestDB client
db = QuestDB(host="localhost", port=9000)

# Query data
async for row in db.query("SELECT * FROM sensors ORDER BY timestamp DESC LIMIT 10"):
print(row)
# Write data
db.write({
"table_name": "my_table",
"symbols": {"symbol_column": "AAPL"},
"columns": {"number_column": 42, "string_column": "Hello, QuestDB!"},
"at": datetime.now()
})

# Query data as a DataFrame
df = await db.query_df("SELECT * FROM sensors WHERE location = 'room1'")
print(df)
# Query data (synchronous)
for row in db.query_sync("SELECT * FROM my_table"):
print(row)

await db.close()
# Query data (asynchronous)
async for row in db.query("SELECT * FROM my_table"):
print(row)

asyncio.run(main())
# Query data as Pandas DataFrame
df = db.query_df_sync("SELECT * FROM my_table")
print(df)
```

## Usage
## Detailed Usage

### Connecting to QuestDB
### Initialization

```python
from questdb_python_client import QuestDB
from py_questdb import QuestDB

# For HTTP interface
db = QuestDB(host="localhost", port=9000)
# Default connection
db = QuestDB()

# For TCP interface
db = QuestDB(host="localhost", port=9009)
# Custom connection
db = QuestDB(host="questdb.example.com", port=9000, username="user", password="pass")
```

### Writing Data

```python
# Write a single message
db.write(
table_name="sensors",
symbols={"location": "room1"},
columns={"temperature": 22.5, "humidity": 60},
at=datetime.now()
)

# Write multiple messages
messages = [
QuestMessage(table_name="sensors", symbols={"location": "room1"}, columns={"temperature": 22.5}, at=datetime.now()),
QuestMessage(table_name="sensors", symbols={"location": "room2"}, columns={"temperature": 23.1}, at=datetime.now())
]
db.write_iter(messages)
from datetime import datetime
from py_questdb.db_types import QuestDBFields

# Single write with auto-flush
db.write({
"table_name": "sensors",
"symbols": {"location": "NYC"},
"columns": {"temperature": 25.5, "humidity": 60},
"at": datetime.now()
})

# Buffer multiple writes
db.buffer_write({
"table_name": "sensors",
"symbols": {"location": "LA"},
"columns": {"temperature": 28.0, "humidity": 55},
"at": datetime.now()
})

# Manually flush buffered writes
db.flush()

# Write using custom message class
class SensorData(msgspec.Struct):
location: str
temperature: float
humidity: int
timestamp: datetime

def to_quest_db_format(self) -> QuestDBFields:
return {
"table_name": "sensors",
"symbols": {"location": self.location},
"columns": {"temperature": self.temperature, "humidity": self.humidity},
"at": self.timestamp
}

sensor_data = SensorData(location="SF", temperature=22.5, humidity=65, timestamp=datetime.now())
db.write(sensor_data)
```

### Querying Data

```python
# Synchronous query
for row in db.query_sync("SELECT * FROM sensors WHERE location = 'NYC'"):
print(f"Temperature: {row['temperature']}, Humidity: {row['humidity']}")

# Asynchronous query
async for row in db.query("SELECT * FROM sensors WHERE location = 'room1'"):
print(row)
async for row in db.query("SELECT * FROM sensors WHERE location = 'LA'"):
print(f"Temperature: {row['temperature']}, Humidity: {row['humidity']}")

# Synchronous query
for row in db.query_sync("SELECT * FROM sensors WHERE location = 'room1'"):
print(row)
# Query into Pandas DataFrame
df = db.query_df_sync("SELECT * FROM sensors")
print(df.describe())

# Query as DataFrame
df = await db.query_df("SELECT * FROM sensors WHERE location = 'room1'")
print(df)
# Query with type hinting
class SensorReading(msgspec.Struct):
location: str
temperature: float
humidity: int

async for reading in db.query("SELECT * FROM sensors", into_type=SensorReading):
print(f"Location: {reading.location}, Temp: {reading.temperature}°C, Humidity: {reading.humidity}%")
```

### Logging

```python
import logging
from py_questdb import QuestDB
from py_questdb.log_handler import QuestDBLogHandler

# Set up QuestDB logging
questdb_client = QuestDB()
handler = QuestDBLogHandler(questdb_client=questdb_client)
logger = logging.getLogger()
logger.addHandler(handler)
logger.setLevel(logging.INFO)

# Log messages
logger.info("System started")
logger.warning("Low disk space")
logger.error("Connection failed", exc_info=True)
```

## Testing

Run the test suite using pytest:

```bash
pytest
```

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

This project is licensed under the [MIT License](LICENSE).

0 comments on commit 0f69b2b

Please sign in to comment.