Skip to content

Error when using table name user with SQLAlchemy #68

@bystepii

Description

@bystepii

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 user as a table name should work without errors.
  • If user is a reserved word in PartiQL, pydynamodb should quote/escape it automatically.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions