diff --git a/Changelog.md b/Changelog.md index 992b33f..f092074 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,7 +4,7 @@ Dataloom **`2.1.0`** ### Release Notes - `dataloom` -We have release the new `dataloom` Version `2.1.0` (`2024-02-12`) +We have release the new `dataloom` Version `2.1.0` (`2024-02-21`) ##### Features @@ -14,13 +14,15 @@ We have release the new `dataloom` Version `2.1.0` (`2024-02-12`) ``` +- updated documentation. + === Dataloom **`2.0.0`** === ### Release Notes - `dataloom` -We have release the new `dataloom` Version `2.0.0` (`2024-02-12`) +We have release the new `dataloom` Version `2.0.0` (`2024-02-21`) ##### Features diff --git a/dataloom/exceptions/__init__.py b/dataloom/exceptions/__init__.py index 2ee3982..e370164 100644 --- a/dataloom/exceptions/__init__.py +++ b/dataloom/exceptions/__init__.py @@ -10,6 +10,10 @@ class InvalidPropertyException(Exception): pass +class InvalidConnectionURI(Exception): + pass + + class TooManyPkException(Exception): pass diff --git a/dataloom/keys.py b/dataloom/keys.py index 4e2537c..59e757b 100644 --- a/dataloom/keys.py +++ b/dataloom/keys.py @@ -9,18 +9,16 @@ class PgConfig: password = "postgres" database = "postgres" user = "postgres" - host = "0.0.0.0" + host = "localhost" port = 5432 - db = "hi" - connection_uri = f"postgresql://{user}:{password}@{host}:{port}/{db}" + connection_uri = f"postgresql://{user}:{password}@{host}:{port}/{database}" else: database = "postgres" user = "postgres" password = "root" host = "localhost" port = 5432 - db = "hi" - connection_uri = f"postgresql://{user}:{password}@{host}:{port}/{db}" + connection_uri = f"postgresql://{user}:{password}@{host}:{port}/{database}" class MySQLConfig: @@ -30,20 +28,18 @@ class MySQLConfig: user = "root" host = "0.0.0.0" port = 3306 - db = "hi" - connection_uri = f"mysql://{user}:{password}@{host}:{port}/{db}" + connection_uri = f"mysql://{user}:{password}@{host}:{port}/{database}" else: database = "hi" user = "root" password = "root" host = "localhost" port = 3306 - db = "hi" - connection_uri = f"mysql://{user}:{password}@{host}:{port}/{db}" + connection_uri = f"mysql://{user}:{password}@{host}:{port}/{database}" class SQLiteConfig: if push: - connection_uri = "sqlite:///database.db" + connection_uri = "sqlite:///hi.db" else: - connection_uri = r"C:\\Users\\RGaridzirai\\OneDrive - Walter Sisulu University\Desktop\\TINASHE CRISPEN G\\orm\\dataloom-py\\hi.db" + connection_uri = "sqlite:///hi.db" diff --git a/dataloom/loom/__init__.py b/dataloom/loom/__init__.py index 4de455c..82e1be2 100644 --- a/dataloom/loom/__init__.py +++ b/dataloom/loom/__init__.py @@ -8,7 +8,7 @@ from dataloom.loom.query import query from dataloom.loom.insert import insert from dataloom.loom.sql import sql as SQL -from dataloom.exceptions import UnsupportedDialectException +from dataloom.exceptions import UnsupportedDialectException, InvalidConnectionURI from dataloom.model import Model from dataloom.statements import GetStatement from dataloom.conn import ConnectionOptionsFactory @@ -37,7 +37,9 @@ class Loom(ILoom): Parameters ---------- - database : str + connection_uri : str, optional + The connection string uri that you can use to connect to the database per dialect. Examples are 'postgresql://user:password@host:port/dbname', 'sqlite:///database.db', 'mysql://user:password@host:port/dbname' for postgres, sqlite and mysql respectively. + database : str, optional The name of the database to which you will connect, for PostgreSQL or MySQL, and the file name for SQLite. dialect : "mysql" | "postgres" | "sqlite" The database dialect to which you want to connect; it is required. @@ -1203,18 +1205,26 @@ def connect( with psycopg2.connect(**options) as conn: self.conn = conn else: + if not self.connection_uri.startswith("postgresql:"): + raise InvalidConnectionURI( + f"Invalid connection uri for the dialect '{self.dialect}' valid examples are ('postgresql://user:password@localhost:5432/dbname')." + ) with psycopg2.connect(self.connection_uri) as conn: self.conn = conn elif self.dialect == "mysql": - options = ( - ConnectionOptionsFactory.get_connection_options( + if self.connection_uri is None: + options = ConnectionOptionsFactory.get_connection_options( **self.connection_options ) - if self.connection_uri is None - else ConnectionOptionsFactory.get_mysql_uri_connection_options( - self.connection_uri - ) - ) + else: + if self.connection_uri.startswith("mysql:"): + options = ConnectionOptionsFactory.get_mysql_uri_connection_options( + self.connection_uri + ) + else: + raise InvalidConnectionURI( + f"Invalid connection uri for the dialect '{self.dialect}' valid examples are ('mysql://user:password@localhost:3306/dbname')." + ) self.conn = connector.connect(**options) elif self.dialect == "sqlite": @@ -1225,12 +1235,24 @@ def connect( if "database" in options: with sqlite3.connect(options.get("database")) as conn: self.conn = conn - else: with sqlite3.connect(**options) as conn: self.conn = conn else: - with sqlite3.connect(self.connection_uri) as conn: + import os + import re + + if not self.connection_uri.startswith("sqlite:"): + raise InvalidConnectionURI( + f"Invalid connection uri for the dialect '{self.dialect}' valid examples are ('sqlite:///db.db', 'sqlite://db.db', 'sqlite:///path/to/database/db.db')." + ) + cwd = os.getcwd() + dbName = os.path.basename(self.connection_uri) + path = os.path.join(re.sub(r"sqlite:(/{2,})", "", self.connection_uri)) + directory = os.path.join(cwd, path).replace(dbName, "") + if not os.path.exists(directory): + os.makedirs(directory) + with sqlite3.connect(os.path.join(directory, dbName)) as conn: self.conn = conn else: raise UnsupportedDialectException( diff --git a/dataloom/tests/mysql/test_connection_uri_mysql.py b/dataloom/tests/mysql/test_connection_uri_mysql.py index 55e2e90..a188b25 100644 --- a/dataloom/tests/mysql/test_connection_uri_mysql.py +++ b/dataloom/tests/mysql/test_connection_uri_mysql.py @@ -79,3 +79,21 @@ def test_connect_correct_connection(self): conn = mysql_loom.connect() conn.close() assert conn is not None + + def test_wrong_connection_uri(self): + from dataloom import Loom + from dataloom.keys import MySQLConfig + from dataloom.exceptions import InvalidConnectionURI + + with pytest.raises(InvalidConnectionURI) as exc_info: + pg_loom = Loom( + dialect="mysql", + connection_uri=f"mysq://{MySQLConfig.user}:{MySQLConfig.password}@{MySQLConfig.host}:{MySQLConfig.port}/{MySQLConfig.database}", + ) + conn = pg_loom.connect() + conn.close() + + assert ( + str(exc_info.value) + == "Invalid connection uri for the dialect 'mysql' valid examples are ('mysql://user:password@localhost:3306/dbname')." + ) diff --git a/dataloom/tests/postgres/test_connection_uri_pg.py b/dataloom/tests/postgres/test_connection_uri_pg.py index fbe0940..edc4899 100644 --- a/dataloom/tests/postgres/test_connection_uri_pg.py +++ b/dataloom/tests/postgres/test_connection_uri_pg.py @@ -24,7 +24,7 @@ def test_connect_with_wrong_password(self): pg_loom = Loom( dialect="postgres", - connection_uri=f"postgresql://{PgConfig.user}:{PgConfig.password+'-'}@{PgConfig.host}:{PgConfig.port}/hi", + connection_uri=f"postgresql://{PgConfig.user}:{PgConfig.password+'-'}@{PgConfig.host}:{PgConfig.port}/{PgConfig.database}", ) with pytest.raises(Exception) as exc_info: conn = pg_loom.connect() @@ -41,7 +41,7 @@ def test_connect_with_wrong_user(self): pg_loom = Loom( dialect="postgres", - connection_uri=f"postgresql://postgre-u:{PgConfig.password}@{PgConfig.host}:{PgConfig.port}/hi", + connection_uri=f"postgresql://postgre-u:{PgConfig.password}@{PgConfig.host}:{PgConfig.port}/{PgConfig.database}", ) with pytest.raises(Exception) as exc_info: conn = pg_loom.connect() @@ -60,7 +60,7 @@ def test_connect_with_wrong_dialect(self): with pytest.raises(UnsupportedDialectException) as exc_info: pg_loom = Loom( dialect="peew", - connection_uri=f"postgresql://{PgConfig.user}:{PgConfig.password}@{PgConfig.host}:{PgConfig.port}/hi", + connection_uri=f"postgresql://{PgConfig.user}:{PgConfig.password}@{PgConfig.host}:{PgConfig.port}/{PgConfig.database}", ) conn = pg_loom.connect() conn.close() @@ -75,9 +75,27 @@ def test_connect_correct_connection(self): pg_loom = Loom( dialect="postgres", - connection_uri=f"postgresql://{PgConfig.user}:{PgConfig.password}@{PgConfig.host}:{PgConfig.port}/hi", + connection_uri=f"postgresql://{PgConfig.user}:{PgConfig.password}@{PgConfig.host}:{PgConfig.port}/{PgConfig.database}", ) conn = pg_loom.connect() conn.close() assert conn is not None + + def test_wrong_connection_uri(self): + from dataloom import Loom + from dataloom.keys import PgConfig + from dataloom.exceptions import InvalidConnectionURI + + with pytest.raises(InvalidConnectionURI) as exc_info: + pg_loom = Loom( + dialect="postgres", + connection_uri=f"postgresl://{PgConfig.user}:{PgConfig.password}@{PgConfig.host}:{PgConfig.port}/{PgConfig.database}", + ) + conn = pg_loom.connect() + conn.close() + + assert ( + str(exc_info.value) + == "Invalid connection uri for the dialect 'postgres' valid examples are ('postgresql://user:password@localhost:5432/dbname')." + ) diff --git a/dataloom/tests/sqlite3/test_connection_uri_sqlite.py b/dataloom/tests/sqlite3/test_connection_uri_sqlite.py index 6535299..70d8081 100644 --- a/dataloom/tests/sqlite3/test_connection_uri_sqlite.py +++ b/dataloom/tests/sqlite3/test_connection_uri_sqlite.py @@ -27,3 +27,20 @@ def test_connect_correct_connection(self): conn = sqlite_loom.connect() conn.close() assert conn is not None + + def test_wrong_connection_uri(self): + from dataloom import Loom + + from dataloom.exceptions import InvalidConnectionURI + + with pytest.raises(InvalidConnectionURI) as exc_info: + pg_loom = Loom( + dialect="sqlite", + connection_uri="sqlite3://hi.db", + ) + conn = pg_loom.connect() + conn.close() + assert ( + str(exc_info.value) + == "Invalid connection uri for the dialect 'sqlite' valid examples are ('sqlite:///db.db', 'sqlite://db.db', 'sqlite:///path/to/database/db.db')." + ) diff --git a/hi.db b/hi.db index f258229..ec81647 100644 Binary files a/hi.db and b/hi.db differ diff --git a/playground.py b/playground.py index 8604e1a..1bed6b8 100644 --- a/playground.py +++ b/playground.py @@ -19,28 +19,28 @@ from typing import Optional from dataclasses import dataclass -# sqlite_loom = Loom( -# connection_uri="sqlite:///database.db", -# dialect="sqlite", -# database="hi.db", -# logs_filename="sqlite-logs.sql", -# sql_logger="console", -# ) +sqlite_loom = Loom( + connection_uri="sqlite://hello/database.db", + dialect="sqlite", + database="hi.db", + logs_filename="sqlite-logs.sql", + sql_logger="console", +) -# conn = sqlite_loom.connect() +conn = sqlite_loom.connect() -pg_loom = Loom( - connection_uri="postgresql://postgres:root@localhost:5432/hi", - dialect="postgres", - sql_logger="console", -) +# pg_loom = Loom( +# connection_uri="postgresql://postgres:root@localhost:5432/hi", +# dialect="postgres", +# sql_logger="console", +# ) -mysql_loom = Loom( - connection_uri="mysql://root:root@localhost:3306/hi", - dialect="mysql", - sql_logger="console", -) +# mysql_loom = Loom( +# connection_uri="mysql://root:root@localhost:3306/hi", +# dialect="mysql", +# sql_logger="console", +# ) class User(Model): @@ -99,9 +99,9 @@ class Category(Model): ) -conn, tables = mysql_loom.connect_and_sync( - [User, Profile, Post, Category], drop=True, force=True -) +# conn, tables = mysql_loom.connect_and_sync( +# [User, Profile, Post, Category], drop=True, force=True +# ) # userId = mysql_loom.insert_one(