I have a custom class which inherits from Python's built-in datetime.date 
class:
# types.py

from datetime import date

class Date(date):
    def __new__(cls, *args, isExceptional: bool = None, **kwargs):
        if len(args) == 1 and isinstance(args[0], date):
            self = super().__new__(
                cls, args[0].year, args[0].month, args[0].day, **kwargs)
        else:
            self = super().__new__(cls, *args, **kwargs)
        if isExceptional is not None:
            self._isOff = True if self.isoweekday() in (6, 7) else False
            if isExceptional:
                self._isOff = not self._isOff
        else:
            self._isOff = None
        return self

    @property
    def isOff(self):
        return self._isOff

    @isOff.setter
    def isOff(self, value: bool):
        if self._isOff is not None:
            raise AttributeError(
                "'isOff' can be set only when it is currently undefined, 
i.e. None"
            )
        else:
            self._isOff = value
In a word Date resembles the original date class, with an additional _isOff 
attribute. Its constructor accepts as arguments either a standard date 
object or whatever acceptable by the original date constructor, along with 
an extra keyword-only one in order to manipulate _isOff value.

And a MariaDB (version 5.5) table:
CREATE TABLE `date` (
    `date` DATE NOT NULL,
    `isOff` BIT(1) NOT NULL DEFAULT b'0',
    PRIMARY KEY (`date`)
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;

I can't figure out the "Declarative" way to map these two, so I tried 
classical mapping:
# orm.py
import sqlalchemy as ORM
date = ORM.Table(
    'date',
    ORM.MetaData(),
    ORM.Column('date', ORM.Date, primary_key=True),
    ORM.Column('isOff', ORM.Boolean)
)

# types.py, after the Date class definition ...
from . import orm
from sqlalchemy.orm import mapper
mapper(Date, orm.date)

With these above, test = Date(2019, 9, 15) gives me
Traceback (most recent call last):
  File 
"c:\users\user\appdata\local\programs\python\python37-32\Lib\runpy.py", 
line 193, in _run_module_as_main
    "__main__", mod_spec)
  File 
"c:\users\user\appdata\local\programs\python\python37-32\Lib\runpy.py", 
line 85, in _run_code
    exec(code, run_globals)
  File "D:\data\work\newsys\newsys\types.py", line 39, in <module>
    test = Date(2019, 9, 15)
TypeError: __init__() takes 1 positional argument but 4 were given
I guess the __init__() mentioned in the error message comes from 
SQLAlchemy's mapping mechanism, since there's no __init__() defined in my 
class nor in the standard date class. Other than this, I can't figure out 
what's going on... what's that "1 positional argument" supposed to be and 
what are supplied as those 4?

How can I map them, with minimal modification to my Date class?

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/01665af1-1e81-45e5-b160-13d6e9914826%40googlegroups.com.

Reply via email to