Skip to content

Commit ee53f8c

Browse files
authored
fix: test failures due to using legacy sqlalchemy api (#1226)
1 parent 9bd824f commit ee53f8c

4 files changed

Lines changed: 56 additions & 61 deletions

File tree

aws_advanced_python_wrapper/__init__.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,16 @@
1414

1515
from logging import DEBUG, getLogger
1616

17+
from aws_advanced_python_wrapper.pep249 import (DatabaseError, DataError,
18+
Error, IntegrityError,
19+
InterfaceError, InternalError,
20+
NotSupportedError,
21+
OperationalError,
22+
ProgrammingError)
1723
from .cleanup import release_resources
1824
from .driver_info import DriverInfo
1925
from .utils.utils import LogUtils
2026
from .wrapper import AwsWrapperConnection
21-
from aws_advanced_python_wrapper.pep249 import (
22-
Error,
23-
InterfaceError,
24-
DatabaseError,
25-
DataError,
26-
OperationalError,
27-
IntegrityError,
28-
InternalError,
29-
ProgrammingError,
30-
NotSupportedError
31-
)
3227

3328
# PEP249 compliance
3429
connect = AwsWrapperConnection.connect
@@ -58,5 +53,6 @@
5853

5954
__version__ = DriverInfo.DRIVER_VERSION
6055

56+
6157
def set_logger(name='aws_advanced_python_wrapper', level=DEBUG, format_string=None):
6258
LogUtils.setup_logger(getLogger(name), level, format_string)

aws_advanced_python_wrapper/sqlalchemy/mysql_orm_dialect.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@
1313
# limitations under the License.
1414

1515
# aws_advanced_python_wrapper/sqlalchemy/sqlalchemy_mysqlconnector_dialect.py
16-
from sqlalchemy.dialects.mysql.mysqlconnector import MySQLDialect_mysqlconnector
17-
import re
18-
19-
from aws_advanced_python_wrapper import AwsWrapperConnection
16+
from sqlalchemy.dialects.mysql.mysqlconnector import \
17+
MySQLDialect_mysqlconnector
2018

2119

2220
class SqlAlchemyOrmMysqlDialect(MySQLDialect_mysqlconnector):
@@ -29,4 +27,3 @@ class SqlAlchemyOrmMysqlDialect(MySQLDialect_mysqlconnector):
2927

3028
name = 'mysql'
3129
driver = 'aws_wrapper_mysqlconnector'
32-

aws_advanced_python_wrapper/sqlalchemy/pg_orm_dialect.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import re
16+
1517
# aws_advanced_python_wrapper/sqlalchemy/sqlalchemy_psycopg_dialect.py
1618
from psycopg import Connection
1719
from sqlalchemy.dialects.postgresql.psycopg import PGDialect_psycopg
18-
import re
1920

2021
from aws_advanced_python_wrapper import AwsWrapperConnection
2122

tests/integration/container/sqlalchemy/test_sqlalchemy_basic.py

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,16 @@
1818

1919
from datetime import date, datetime, time, timezone
2020
from decimal import Decimal
21-
from typing import Any
21+
from typing import Any, List, Optional
2222

2323
import pytest
24+
from sqlalchemy import (JSON, BigInteger, Boolean, Date, DateTime, Float,
25+
ForeignKey, Numeric, SmallInteger, String, Text, Time,
26+
and_, create_engine, or_, text)
27+
from sqlalchemy.orm import (DeclarativeBase, Mapped, Session, joinedload,
28+
mapped_column, relationship, sessionmaker,
29+
subqueryload)
2430
from sqlalchemy.sql import func
25-
from sqlalchemy.orm import (
26-
declarative_base, sessionmaker, relationship, Session, joinedload,
27-
subqueryload
28-
)
29-
from sqlalchemy import (
30-
create_engine, Column, ForeignKey, Integer, BigInteger, SmallInteger,
31-
Float, Numeric, String, Boolean, Date, Time, DateTime, Text, JSON, or_,
32-
and_, text
33-
)
3431

3532
from tests.integration.container.utils.rds_test_utility import RdsTestUtility
3633
from ..utils.conditions import (disable_on_features, enable_on_deployments,
@@ -40,74 +37,76 @@
4037
from ..utils.test_environment import TestEnvironment
4138
from ..utils.test_environment_features import TestEnvironmentFeatures
4239

43-
class Base:
44-
__allow_unmapped__ = True
4540

46-
Base = declarative_base(cls=Base)
41+
class Base(DeclarativeBase):
42+
pass
43+
4744

4845
class TestModel(Base):
4946
"""Basic test model for SQLAlchemy ORM functionality"""
5047
__tablename__ = 'sqlalchemy_test_model'
5148

52-
id = Column(Integer, primary_key=True)
49+
id: Mapped[int] = mapped_column(primary_key=True)
50+
name: Mapped[str] = mapped_column(String(100))
51+
email: Mapped[str] = mapped_column(String(254), unique=True)
52+
age: Mapped[int] = mapped_column()
53+
is_active: Mapped[Optional[bool]] = mapped_column(Boolean, default=True)
54+
created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, default=datetime.now(timezone.utc))
5355

54-
name = Column(String(100), nullable=False)
55-
email = Column(String(254), nullable=False, unique=True)
56-
age = Column(Integer, nullable=False)
57-
is_active = Column(Boolean, default=True)
58-
created_at = Column(DateTime, default=datetime.now(timezone.utc))
5956

6057
class DataTypeModel(Base):
6158
"""Model for testing various data types"""
6259
__tablename__ = 'sqlalchemy_data_type_model'
6360

64-
id = Column(Integer, primary_key=True)
61+
id: Mapped[int] = mapped_column(primary_key=True)
6562

6663
# String fields
67-
string_field = Column(String(255))
68-
text_field = Column(Text)
64+
string_field: Mapped[Optional[str]] = mapped_column(String(255))
65+
text_field: Mapped[Optional[str]] = mapped_column(Text)
6966

7067
# Numeric fields
71-
integer_field = Column(Integer)
72-
small_integer_field = Column(SmallInteger)
73-
big_integer_field = Column(BigInteger)
74-
numeric_field = Column(Numeric(10, 2))
75-
float_field = Column(Float)
68+
integer_field: Mapped[Optional[int]] = mapped_column()
69+
small_integer_field: Mapped[Optional[int]] = mapped_column(SmallInteger)
70+
big_integer_field: Mapped[Optional[int]] = mapped_column(BigInteger)
71+
numeric_field: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 2))
72+
float_field: Mapped[Optional[float]] = mapped_column(Float)
7673

7774
# Boolean field
78-
boolean_field = Column(Boolean, default=False)
75+
boolean_field: Mapped[Optional[bool]] = mapped_column(Boolean, default=False)
7976

8077
# Date/Time fields
81-
date_field = Column(Date)
82-
time_field = Column(Time)
83-
datetime_field = Column(DateTime)
78+
date_field: Mapped[Optional[date]] = mapped_column(Date)
79+
time_field: Mapped[Optional[time]] = mapped_column(Time)
80+
datetime_field: Mapped[Optional[datetime]] = mapped_column(DateTime)
8481

8582
# JSON field (MySQL 5.7+)
86-
json_field = Column(JSON)
83+
json_field: Mapped[Optional[Any]] = mapped_column(JSON)
84+
8785

8886
class Author(Base):
8987
"""Author model for relationship testing"""
9088
__tablename__ = 'sqlalchemy_author'
9189

92-
id = Column(Integer, primary_key=True)
93-
name = Column(String(100), nullable=False)
94-
email = Column(String(254), nullable=False)
95-
birth_date = Column(Date)
90+
id: Mapped[int] = mapped_column(primary_key=True)
91+
name: Mapped[str] = mapped_column(String(100))
92+
email: Mapped[str] = mapped_column(String(254))
93+
birth_date: Mapped[Optional[date]] = mapped_column(Date)
94+
95+
books: Mapped[List[Book]] = relationship(back_populates='author', cascade='all, delete-orphan')
9696

97-
books = relationship('Book', back_populates='author', cascade='all, delete-orphan')
9897

9998
class Book(Base):
10099
"""Book model for relationship testing"""
101100
__tablename__ = 'sqlalchemy_book'
102101

103-
id = Column(Integer, primary_key=True)
104-
title = Column(String(200), nullable=False)
105-
author_id = Column(Integer, ForeignKey("sqlalchemy_author.id"), nullable=False)
106-
publication_date = Column(Date, nullable=False)
107-
pages = Column(Integer, nullable=False)
108-
price = Column(Numeric(8, 2), nullable=False)
102+
id: Mapped[int] = mapped_column(primary_key=True)
103+
title: Mapped[str] = mapped_column(String(200))
104+
author_id: Mapped[int] = mapped_column(ForeignKey("sqlalchemy_author.id"))
105+
publication_date: Mapped[date] = mapped_column(Date)
106+
pages: Mapped[int] = mapped_column()
107+
price: Mapped[Decimal] = mapped_column(Numeric(8, 2))
109108

110-
author = relationship('Author', back_populates='books')
109+
author: Mapped[Author] = relationship(back_populates='books')
111110

112111
@enable_on_engines([DatabaseEngine.MYSQL]) # MySQL Specific until PG is implemented
113112
@enable_on_deployments([DatabaseEngineDeployment.AURORA, DatabaseEngineDeployment.RDS_MULTI_AZ_CLUSTER])
@@ -680,6 +679,7 @@ def test_sqlalchemy_distinct_queries(self, test_environment: TestEnvironment, se
680679
def test_sqlalchemy_load_only_and_defer(self, test_environment: TestEnvironment, session):
681680
"""Test SQLAlchemy load_only() and defer() for query optimization"""
682681
from sqlalchemy.orm import defer, load_only
682+
683683
# Ensure clean slate
684684
session.query(TestModel).delete()
685685
session.commit()
@@ -747,6 +747,7 @@ def test_sqlalchemy_batch_retrieval(self, test_environment: TestEnvironment, ses
747747
def test_sqlalchemy_conditional_expressions(self, test_environment: TestEnvironment, session):
748748
"""Test SQLAlchemy case() conditional expressions"""
749749
from sqlalchemy import String, case
750+
750751
# Ensure clean slate
751752
session.query(TestModel).delete()
752753
session.commit()

0 commit comments

Comments
 (0)