-
Notifications
You must be signed in to change notification settings - Fork 4
Labels
enhancementNew feature or requestNew feature or request
Description
Environment
- Python version: 3.11.13
- SQLAlchemy version: 2.0.43
- pydynamodb version: 0.7.3
Description
When defining a model with the table name "user", pydynamodb fails when inserting a row. If the table name is changed (e.g., "usertable"), it works correctly.
Minimal Reproducible Example
import uuid, hashlib
from sqlmodel import SQLModel, Field, Session, select
from pydynamodb import sqlalchemy_dynamodb
from sqlalchemy.engine import create_engine
session = boto3.Session()
credentials = session.get_credentials()
aws_access_key_id = credentials.access_key
aws_secret_access_key = credentials.secret_key
region_name = session.region_name
conn_str = (
"dynamodb://{aws_access_key_id}:{aws_secret_access_key}@dynamodb.{region_name}.amazonaws.com:443"
+ "?verify=false"
).format(
aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key,
region_name=region_name,
)
engine = create_engine(conn_str, echo=True)
class User(SQLModel):
__table_args__ = {"extend_existing": True}
id: str = Field(
default_factory=lambda: uuid.uuid4().hex, primary_key=True, index=True
)
username: str = Field(unique=True)
username_lower: str = Field(unique=True)
password: str
def create_user(usn, pwd, user_id=None) -> bool:
with Session(engine) as session:
statement = select(User).where(User.username_lower == usn.lower())
result = session.exec(statement).all()
if result:
print(f'User "{usn}" already exists')
return False
else:
hashed_password = hashlib.sha256(pwd.encode()).hexdigest()
user = User(
id=user_id,
username=usn,
username_lower=usn.lower(),
password=hashed_password,
)
session.add(user)
session.commit()
return True
create_user("admin", "admin")Observed Behavior
DynamoDB returns an error:
2025-09-29 09:56:10,783 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2025-09-29 09:56:10,797 INFO sqlalchemy.engine.Engine SELECT id, username, username_lower, password
FROM user
WHERE username_lower = ?
2025-09-29 09:56:10,799 INFO sqlalchemy.engine.Engine [generated in 0.00230s] ('admin',)
/home/user/miniconda3/envs/test/lib/python3.11/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host 'localhost'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
warnings.warn(
2025-09-29 09:56:11,410 INFO sqlalchemy.engine.Engine INSERT INTO user VALUE {'id': ?, 'username': ?, 'username_lower': ?, 'password': ?}
2025-09-29 09:56:11,412 INFO sqlalchemy.engine.Engine [generated in 0.00235s] ('7fcb2a41b1ae4a94bcd37d9e80aa3aea', 'admin', 'admin', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918')
/home/user/miniconda3/envs/test/lib/python3.11/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host 'localhost'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
warnings.warn(
Failed to execute statement.
Traceback (most recent call last):
File "/home/user/miniconda3/envs/test/lib/python3.11/site-packages/pydynamodb/executor.py", line 85, in _dispatch_api_call
response = retry_api_call(
^^^^^^^^^^^^^^^
File "/home/user/miniconda3/envs/test/lib/python3.11/site-packages/pydynamodb/util.py", line 111, in retry_api_call
return retry(func, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/user/miniconda3/envs/test/lib/python3.11/site-packages/tenacity/__init__.py", line 379, in __call__
do = self.iter(retry_state=retry_state)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/user/miniconda3/envs/test/lib/python3.11/site-packages/tenacity/__init__.py", line 314, in iter
return fut.result()
^^^^^^^^^^^^
File "/home/user/miniconda3/envs/test/lib/python3.11/concurrent/futures/_base.py", line 449, in result
return self.__get_result()
^^^^^^^^^^^^^^^^^^^
File "/home/user/miniconda3/envs/test/lib/python3.11/concurrent/futures/_base.py", line 401, in __get_result
raise self._exception
File "/home/user/miniconda3/envs/test/lib/python3.11/site-packages/tenacity/__init__.py", line 382, in __call__
result = fn(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^
File "/home/user/miniconda3/envs/test/lib/python3.11/site-packages/botocore/client.py", line 602, in _api_call
return self._make_api_call(operation_name, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/user/miniconda3/envs/test/lib/python3.11/site-packages/botocore/context.py", line 123, in wrapper
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/home/user/miniconda3/envs/test/lib/python3.11/site-packages/botocore/client.py", line 1078, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the ExecuteStatement operation: Statement wasn't well formed, can't be processed: Expected identifier for simple path
2025-09-29 09:56:11,614 INFO sqlalchemy.engine.Engine ROLLBACK
Expected Behavior
- Using
useras a table name should work without errors. - If
useris a reserved word in PartiQL, pydynamodb should quote/escape it automatically.
bystepii and passrenacanadilbystepii
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request