From 7abf390d1320fe686cc31017a4f964fc3a779428 Mon Sep 17 00:00:00 2001 From: Michael Hadorn Date: Thu, 19 Dec 2024 17:01:10 +0100 Subject: [PATCH 1/3] make sqlalchemy 2.0 compatible --- sqlalchemy_sqlany/base.py | 133 ++++++++++++++++++++++++-------------- 1 file changed, 83 insertions(+), 50 deletions(-) diff --git a/sqlalchemy_sqlany/base.py b/sqlalchemy_sqlany/base.py index 70b21e7..6cbabc3 100644 --- a/sqlalchemy_sqlany/base.py +++ b/sqlalchemy_sqlany/base.py @@ -294,7 +294,7 @@ def post_exec(self): def get_lastrowid(self): cursor = self.create_cursor() cursor.execute("SELECT @@identity AS lastrowid") - lastrowid = cursor.fetchone()[0] + lastrowid = cursor.first()[0] cursor.close() return lastrowid @@ -500,9 +500,13 @@ def get_table_id(self, connection, table_name, schema=None, **kw): if isinstance(table_name, str): table_name = table_name.encode("ascii") # end Py2K - result = connection.execute(TABLEID_SQL, - schema_name=schema, - table_name=table_name) + result = connection.execute( + TABLEID_SQL, + { + 'schema_name': schema + , 'table_name': table_name + } + ) table_id = result.scalar() if table_id is None: raise exc.NoSuchTableError(table_name) @@ -527,7 +531,7 @@ def get_columns(self, connection, table_name, schema=None, **kw): ORDER BY col.column_id """) - results = connection.execute(COLUMN_SQL, table_id=table_id) + results = connection.execute(COLUMN_SQL, {'table_id': table_id}) columns = [] for (name, type_, nullable, autoincrement, default, precision, scale, @@ -593,10 +597,10 @@ def get_foreign_keys(self, connection, table_name, schema=None, **kw): WHERE c.table_id = :table_id """) - results = connection.execute(COLUMN_SQL, table_id=table_id) + results = connection.execute(COLUMN_SQL, {'table_id': table_id}) columns = {} for col in results: - columns[col["id"]] = col["name"] + columns[col.id] = col.name column_cache[table_id] = columns REFCONSTRAINT_SQL = text(""" @@ -607,8 +611,12 @@ def get_foreign_keys(self, connection, table_name, schema=None, **kw): WHERE fk.foreign_table_id = :table_id and i.index_category=2 """) - referential_constraints = connection.execute(REFCONSTRAINT_SQL, - table_id=table_id) + referential_constraints = connection.execute( + REFCONSTRAINT_SQL + , { + 'table_id': table_id + } + ) REFTABLE_SQL = text(""" SELECT t.table_name AS name, u.name AS "schema" @@ -617,23 +625,26 @@ def get_foreign_keys(self, connection, table_name, schema=None, **kw): """) for r in referential_constraints: - reftable_id = r["reftable_id"] - foreign_index_id = r["foreign_index_id"] + reftable_id = r.reftable_id + foreign_index_id = r.foreign_index_id if reftable_id not in table_cache: - c = connection.execute(REFTABLE_SQL, table_id=reftable_id) - reftable = c.fetchone() + c = connection.execute( + REFTABLE_SQL + , {'table_id': reftable_id} + ) + reftable = c.first() c.close() - table_info = {"name": reftable["name"], "schema": None} + table_info = {"name": reftable.name, "schema": None} if (schema is not None or - reftable["schema"] != self.default_schema_name): - table_info["schema"] = reftable["schema"] + reftable.schema != self.default_schema_name): + table_info["schema"] = reftable.schema table_cache[reftable_id] = table_info - results = connection.execute(COLUMN_SQL, table_id=reftable_id) + results = connection.execute(COLUMN_SQL, {'table_id': reftable_id}) reftable_columns = {} for col in results: - reftable_columns[col["id"]] = col["name"] + reftable_columns[col.id] = col.name column_cache[reftable_id] = reftable_columns reftable = table_cache[reftable_id] @@ -651,20 +662,24 @@ def get_foreign_keys(self, connection, table_name, schema=None, **kw): and fk.foreign_table_id = :table_id and fk.foreign_index_id = :foreign_index_id """) - ref_cols = connection.execute(REFCOLS_SQL, - table_id=table_id, - reftable_id=reftable_id, - foreign_index_id=foreign_index_id) + ref_cols = connection.execute( + REFCOLS_SQL + , { + 'table_id': table_id, + 'reftable_id': reftable_id, + 'foreign_index_id': foreign_index_id + } + ) for rc in ref_cols: - constrained_columns.append(columns[rc["fokey"]]) - referred_columns.append(reftable_columns[rc["refkey"]]) + constrained_columns.append(columns[rc.fokey]) + referred_columns.append(reftable_columns[rc.refkey]) fk_info = { "constrained_columns": constrained_columns, - "referred_schema": reftable["schema"], - "referred_table": reftable["name"], + "referred_schema": reftable['schema'], + "referred_table": reftable['name'], "referred_columns": referred_columns, - "name": r["name"] + "name": r.name } foreign_keys.append(fk_info) @@ -686,7 +701,7 @@ def get_indexes(self, connection, table_name, schema=None, **kw): WHERE t.table_id = :table_id and i.index_category = 3 """) - results = connection.execute(INDEX_SQL, table_id=table_id) + results = connection.execute(INDEX_SQL, {'table_id': table_id}) indexes = [] for r in results: INDEXCOL_SQL = text(""" @@ -696,11 +711,16 @@ def get_indexes(self, connection, table_name, schema=None, **kw): WHERE ic.index_id = :index_id and ic.table_id = :table_id ORDER BY ic.sequence ASC """) - idx_cols = connection.execute(INDEXCOL_SQL, index_id=r["index_id"], - table_id=table_id) - column_names = [ic["col"] for ic in idx_cols] - index_info = {"name": r["name"], - "unique": bool(r["unique"]), + idx_cols = connection.execute( + INDEXCOL_SQL + , { + 'index_id': r.index_id + , 'table_id': table_id + } + ) + column_names = [ic.col for ic in idx_cols] + index_info = {"name": r.name, + "unique": bool(r.unique), "column_names": column_names} indexes.append(index_info) @@ -719,8 +739,8 @@ def get_pk_constraint(self, connection, table_name, schema=None, **kw): WHERE t.table_id = :table_id and i.index_category = 1 """) - results = connection.execute(PK_SQL, table_id=table_id) - pks = results.fetchone() + results = connection.execute(PK_SQL, {'table_id': table_id}) + pks = results.first() results.close() if not pks: @@ -733,11 +753,18 @@ def get_pk_constraint(self, connection, table_name, schema=None, **kw): join sys.systabcol tc on (ic.table_id=tc.table_id and ic.column_id=tc.column_id) WHERE ic.index_id = :index_id and ic.table_id = :table_id """) - pk_cols = connection.execute(PKCOL_SQL, index_id=pks["index_id"], - table_id=table_id ) - column_names = [pkc["col"] for pkc in pk_cols] - return {"constrained_columns": column_names, - "name": pks["name"]} + pk_cols = connection.execute( + PKCOL_SQL + , { + 'index_id': pks.index_id + , 'table_id': table_id + } + ) + column_names = [pkc.col for pkc in pk_cols] + return { + "constrained_columns": column_names, + "name": pks.name + } @reflection.cache def get_unique_constraints(self, connection, table_name, schema=None, **kw): @@ -752,7 +779,7 @@ def get_unique_constraints(self, connection, table_name, schema=None, **kw): WHERE t.table_id = :table_id and i.index_category = 3 and i."unique"=2 """) - results = connection.execute(INDEX_SQL, table_id=table_id) + results = connection.execute(INDEX_SQL, {'table_id': table_id}) indexes = [] for r in results: INDEXCOL_SQL = text(""" @@ -762,10 +789,15 @@ def get_unique_constraints(self, connection, table_name, schema=None, **kw): WHERE ic.index_id = :index_id and ic.table_id = :table_id ORDER BY ic.sequence ASC """) - idx_cols = connection.execute(INDEXCOL_SQL, index_id=r["index_id"], - table_id=table_id) - column_names = [ic["col"] for ic in idx_cols] - index_info = {"name": r["name"], + idx_cols = connection.execute( + INDEXCOL_SQL + , { + 'index_id': r.index_id + , 'table_id': table_id + } + ) + column_names = [ic.col for ic in idx_cols] + index_info = {"name": r.name, "column_names": column_names} indexes.append(index_info) @@ -795,9 +827,10 @@ def get_table_names(self, connection, schema=None, **kw): if isinstance(schema, str): schema = schema.encode("ascii") # end Py2K - tables = connection.execute(TABLE_SQL, schema_name=schema) + tables = connection.execute(TABLE_SQL, {"schema_name": schema}) + # tables = result.fetchall() - return [t["name"] for t in tables] + return [t.name for t in tables] @reflection.cache def get_view_definition(self, connection, view_name, schema=None, **kw): @@ -816,7 +849,7 @@ def get_view_definition(self, connection, view_name, schema=None, **kw): if isinstance(view_name, str): view_name = view_name.encode("ascii") # end Py2K - view = connection.execute(VIEW_DEF_SQL, view_name=view_name) + view = connection.execute(VIEW_DEF_SQL, {'view_name': view_name}) return view.scalar() @@ -836,9 +869,9 @@ def get_view_names(self, connection, schema=None, **kw): if isinstance(schema, str): schema = schema.encode("ascii") # end Py2K - views = connection.execute(VIEW_SQL, schema_name=schema) + views = connection.execute(VIEW_SQL, {'schema_name': schema}) - return [v["name"] for v in views] + return [v.name for v in views] def has_table(self, connection, table_name, schema=None): try: From 4c5657c4b8ffad0509d54952f2044b558e8775e6 Mon Sep 17 00:00:00 2001 From: MrJack91 Date: Mon, 6 Jan 2025 14:45:25 +0100 Subject: [PATCH 2/3] Update README.rst --- README.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.rst b/README.rst index 6d7931d..34133b3 100644 --- a/README.rst +++ b/README.rst @@ -2,6 +2,15 @@ .. Copyright (c) 2013 SAP AG or an SAP affiliate company. All rights reserved. .. *************************************************************************** + +CHANGES to official sqlalchemy-sqlany +===================================== +Make it compatible with sqlalchemy 2.0 +* bind params using dictionary instead of kwrgs +* access columns as property not as list-element + + + sqlalchemy-sqlany ================= This project provides a SQLAlchemy dialect for communicating with a SQL Anywhere From 9bef1582e4c70c108517d2f9c81467ea9dd4176a Mon Sep 17 00:00:00 2001 From: MrJack91 Date: Mon, 6 Jan 2025 14:45:37 +0100 Subject: [PATCH 3/3] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 34133b3..f32af0e 100644 --- a/README.rst +++ b/README.rst @@ -6,11 +6,11 @@ CHANGES to official sqlalchemy-sqlany ===================================== Make it compatible with sqlalchemy 2.0 + * bind params using dictionary instead of kwrgs * access columns as property not as list-element - sqlalchemy-sqlany ================= This project provides a SQLAlchemy dialect for communicating with a SQL Anywhere