Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/dev 2542 upgrade sqlalchemy1.4 #240

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
---
include:
- project: nci-gdc/gitlab-templates
ref: master
ref: 0.7.11
file:
- templates/artifacts/python-library.yaml

tox:
parallel:
matrix:
- LANGUAGE_VERSION:
- python3.8
- python3.9
- python3.10
- python3.11
- python3.12
services:
- name: docker.osdc.io/ncigdc/ci-postgres-13:${BASE_CONTAINER_VERSION}
alias: postgres
variables:
BASE_CONTAINER_VERSION: 2.3.1
# these are for postgres docker
POSTGRES_DB: automated_test
POSTGRES_USER: test
Expand Down
4 changes: 2 additions & 2 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
"filename": ".gitlab-ci.yml",
"hashed_secret": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3",
"is_verified": false,
"line_number": 17,
"line_number": 24,
"is_secret": false
}
],
Expand All @@ -149,5 +149,5 @@
}
]
},
"generated_at": "2024-07-26T21:01:14Z"
"generated_at": "2024-09-06T17:02:29Z"
}
36 changes: 0 additions & 36 deletions .travis.yml

This file was deleted.

7 changes: 3 additions & 4 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,22 @@ classifiers =
Topic :: Internet
Topic :: Software Development :: Libraries :: Python Modules
Programming Language :: Python
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Development Status :: 5 - Production/Stable

[options]
zip_safe = True
packages = find:
package_dir =
=src
python_requires = >=3.7
python_requires = >=3.8
include_package_data = True
install_requires =
psycopg2
sqlalchemy>=1.3,<1.4
sqlalchemy[postgresql]~=1.4
xlocal
rstr

Expand Down
14 changes: 14 additions & 0 deletions src/psqlgraph/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,17 @@
from psqlgraph.util import pg_property, sanitize, validate
from psqlgraph.voided_edge import VoidedEdge
from psqlgraph.voided_node import VoidedNode

__all__ = (
"Edge",
"Node",
"PolyEdge",
"PolyNode",
"PsqlGraphDriver",
"VoidedEdge",
"VoidedNode",
"create_all",
"pg_property",
"sanitize",
"validate",
)
38 changes: 16 additions & 22 deletions src/psqlgraph/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from sqlalchemy import event
import inspect
from typing import ClassVar

from sqlalchemy.dialects import postgresql
from sqlalchemy.ext import declarative
from sqlalchemy.ext.declarative import declared_attr
Expand All @@ -18,6 +20,18 @@ class CommonBase:
_session_hooks_before_insert = []
_session_hooks_before_update = []
_session_hooks_before_delete = []
__pg_properties__: ClassVar[dict]

def __init_subclass__(cls) -> None:
cls.__pg_properties__ = {}
pg_properties = (
(k, v) for k, v in vars(cls).items() if getattr(v, "__pg_setter__", False)
)

for name, property in pg_properties:
h_prop = _create_hybrid_property(name, property)
setattr(cls, name, h_prop)
cls.__pg_properties__[name] = property.__pg_types__

# ======== Columns ========
created = schema.Column(
Expand Down Expand Up @@ -237,7 +251,7 @@ def get_pg_properties(cls):
return cls.__pg_properties__


def create_hybrid_property(name, fset):
def _create_hybrid_property(name, fset):
@hybrid_property
def hybrid_prop(instance):
# Note: this does not use an 'in' clause or a .get() with a
Expand All @@ -256,26 +270,6 @@ def hybrid_prop(instance, value):
return hybrid_prop


@event.listens_for(CommonBase, "mapper_configured", propagate=True)
def create_hybrid_properties(mapper, cls):
# This dictionary will be a property name to allowed types
# dictionary. It will be populated at mapper configuration using
# all model properties defined with @pg_property
cls.__pg_properties__ = {}

for pg_attr in dir(cls):
if pg_attr in ["properties", "props", "system_annotations", "sysan"]:
continue

f = getattr(cls, pg_attr)
if not getattr(f, "__pg_setter__", False):
continue

h_prop = create_hybrid_property(pg_attr, f)
setattr(cls, pg_attr, h_prop)
cls.__pg_properties__[pg_attr] = f.__pg_types__


class VoidedBaseClass:
@hybrid_property
def props(self):
Expand Down
4 changes: 1 addition & 3 deletions src/psqlgraph/psql.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ def __init__(self, host, user, password, database, **kwargs):

# Construct connection string
host = "" if host is None else host
conn_str = "postgresql://{user}:{password}@{host}/{database}".format(
user=user, password=password, host=host, database=database
)
conn_str = f"postgresql+psycopg2://{user}:{password}@{host}/{database}"
if kwargs["isolation_level"] not in self.acceptable_isolation_levels:
logger.warning(
(
Expand Down
17 changes: 12 additions & 5 deletions src/psqlgraph/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ def entity(self):
entity.

"""
if self._last_joined_entity:
return self._last_joined_entity.entity

return self._joinpoint_zero().entity
return self.column_descriptions[0]["entity"]

# ======== Edges ========
def with_edge_to_node(self, edge_type, target_node):
Expand Down Expand Up @@ -208,13 +210,18 @@ def path(self, *paths):
query.path().reset_joinpoint().filter()

"""
entities = [p.strip() for path in paths for p in path.split(".")]
entities = (p.strip() for path in paths for p in path.split("."))
query = self

assert (
not self.entity().is_abstract_base()
), "Please narrow your search by specifying a node subclass"
for e in entities:
self = self.join(*getattr(self.entity(), e).attr)
return self

for entity in entities:
proxy = getattr(query.entity(), entity)
query = query.join(proxy.local_attr).join(proxy.remote_attr)

return query

def _get_link_details(self, entity, link_name):
""" "Lookup the (edge_class, left_edge_id, right_edge_id, node_class)
Expand Down
7 changes: 6 additions & 1 deletion src/psqlgraph/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@ def __init__(self, *args, **kwargs):
self.package_namespace = kwargs.pop("package_namespace", None)
super().__init__(*args, **kwargs)

def _autobegin(self):
if self._psqlgraph_closed:
raise exc.SessionClosedError("session closed")

return super()._autobegin()

@inherit_docstring_from(Session)
def connection(self, *args, **kwargs):

if self._psqlgraph_closed:
raise exc.SessionClosedError("session closed")

Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = py37,py38,py39,py310,py311
envlist = py3{8,9,10,11,12}
skip_missing_interpreters = True
isolated_build = True

Expand Down