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

objects.create doesn't use __init__ or pydantic validator #245

Closed
jinserk opened this issue Jun 17, 2021 · 1 comment
Closed

objects.create doesn't use __init__ or pydantic validator #245

jinserk opened this issue Jun 17, 2021 · 1 comment
Labels
bug Something isn't working

Comments

@jinserk
Copy link

jinserk commented Jun 17, 2021

Describe the bug
As discussed in #230, an ormar.Model doesn't use __init__() or pydantic's validator when its object.create() is used

To Reproduce

from typing import ClassVar                                                                                                                                                                                                                                                     
import sqlite3                                                                                                                                                                                                                                                                  
import uuid                                                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                                                                
import sqlalchemy                                                                                                                                                                                                                                                               
import databases                                                                                                                                                                                                                                                                
import ormar                                                                                                                                                                                                                                                                    
from pydantic import root_validator                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                
class Connection(sqlite3.Connection):                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                
    def __init__(self, *args, **kwargs):  # pragma: no cover                                                                                                                                                                                                                    
        super().__init__(*args, **kwargs)                                                                                                                                                                                                                                       
        self.execute("PRAGMA auto_vacuum = 1;")                                                                                                                                                                                                                                 
        self.execute("PRAGMA foreign_keys = 1;")                                                                                                                                                                                                                                
        self.execute("PRAGMA journal_mode = wal;")                                                                                                                                                                                                                              
        self.execute(f"PRAGMA cache_size = {2 ** 13};")                                                                                                                                                                                                                         
        self.execute(f"PRAGMA mmap_size = {2 ** 30};")


DB_URL = "sqlite:///local.db"

database = databases.Database(DB_URL, force_rollback=True, factory=Connection)
metadata = sqlalchemy.MetaData()

class BaseMeta(ormar.ModelMeta):
    database = database
    metadata = metadata

class Mol(ormar.Model):
    # fixed namespace to generate always unique uuid from the smiles
    _UUID_NAMESPACE: ClassVar[uuid.UUID] = uuid.UUID('12345678-abcd-1234-abcd-123456789abc')

    class Meta(BaseMeta):
        tablename = "mols"

    id: str = ormar.UUID(primary_key=True, index=True, uuid_format='hex')
    smiles: str = ormar.String(nullable=False, unique=True, max_length=256)

    def __init__(self, **kwargs):
        # this is required to generate id from smiles in init, if id is not given
        if 'id' not in kwargs:
            kwargs['id'] = self._UUID_NAMESPACE
        super().__init__(**kwargs)

    @root_validator()
    def make_canonical_smiles_and_uuid(cls, values):
        values['id'], values['smiles'] = cls.uuid(values['smiles'])
        return values

    @classmethod
    def uuid(cls, smiles):
        id = uuid.uuid5(cls._UUID_NAMESPACE, smiles)
        return id, smiles

engine = sqlalchemy.create_engine(DB_URL)
metadata.create_all(engine)

async def mol_subtask():
    mol = await Mol.objects.create(smiles="Cc1ccccc1")
    c = await Mol.objects.count()

asyncio.run(mol_subtask())

Expected behavior
Generate a Mol object without error since the missing id will be generated from __init__ or validator

Versions (please complete the following information):

  • Database backend used (mysql/sqlite/postgress): sqlite3
  • Python version: 3.9.5
  • ormar version: 0.10.11
  • pydantic version: 1.8.2
  • if applicable fastapi version: Not applicable
@jinserk jinserk added the bug Something isn't working label Jun 17, 2021
@collerek collerek mentioned this issue Jun 22, 2021
@collerek
Copy link
Owner

Fixed in 0.10.12 (via #251)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants