Source code for sqlathanor.declarative.generate_model

# -*- coding: utf-8 -*-

# The lack of a module docstring for this module is **INTENTIONAL**.
# The module is imported into the documentation using Sphinx's autodoc
# extension, and its member function documentation is automatically incorporated
# there as needed.

from validator_collection import checkers

from sqlathanor.declarative.base_model import BaseModel
from sqlathanor.declarative.declarative_base import declarative_base
from sqlathanor.attributes import AttributeConfiguration, validate_serialization_config
from sqlathanor.utilities import parse_yaml, parse_json, parse_csv, read_csv_data
from sqlathanor.default_deserializers import get_type_mapping
from sqlathanor.schema import Column

[docs]def generate_model_from_dict(serialized_dict, tablename, primary_key, cls = BaseModel, serialization_config = None, skip_nested = True, default_to_str = False, type_mapping = None, base_model_attrs = None, **kwargs): """Generate a :term:`model class` from a serialized :class:`dict <python:dict>`. .. versionadded: 0.3.0 .. note:: This function *cannot* programmatically create :term:`relationships <relationship>`, :term:`hybrid properties <hybrid property>`, or :term:`association proxies <association proxy>`. :param serialized_dict: The :class:`dict <python:dict>` that has been de-serialized from a given string. Keys will be treated as column names, while value data types will determine :term:`model attribute` data types. :type serialized_dict: :class:`dict <python:dict>` :param tablename: The name of the SQL table to which the model corresponds. :type tablename: :class:`str <python:str>` :param primary_key: The name of the column/key that should be used as the table's primary key. :type primary_key: :class:`str <python:str>` :param cls: The base class to use when generating a new :term:`model class`. Defaults to :class:`BaseModel` to provide serialization/de-serialization support. If a :class:`tuple <python:tuple>` of classes, will include :class:`BaseModel` in that list of classes to mixin serialization/de-serialization support. If not :obj:`None <python:None>` and not a :class:`tuple <python:tuple>`, will mixin :class:`BaseModel` with the value passed to provide serialization/de-serialization support. :type cls: :obj:`None <python:None>` / :class:`tuple <python:tuple>` of classes / class object :param serialization_config: Collection of :class:`AttributeConfiguration <sqlathanor.attributes.AttributeConfiguration>` that determine the generated model's :term:`serialization`/:term:`de-serialization` :ref:`configuration <configuration>`. If :obj:`None <python:None>`, will support serialization and de-serialization across all keys in ``serialized_dict``. Defaults to :obj:`None <python:None>`. :type serialization_config: Iterable of :class:`AttributeConfiguration <sqlathanor.attributes.AttributeConfiguration>` or coercable :class:`dict <python:dict>` objects / :obj:`None <python:None>` :param skip_nested: If ``True`` then any keys in ``serialized_dict`` that feature nested items (e.g. iterables, :class:`dict <python:dict>` objects, etc.) will be ignored. If ``False``, will treat serialized items as :class:`str <python:str>`. Defaults to ``True``. :type skip_nested: :class:`bool <python:bool>` :param default_to_str: If ``True``, will automatically set a key/column whose value type cannot be determined to ``str`` (:class:`Text <sqlalchemy:sqlalchemy.types.Text>`). If ``False``, will use the value type's ``__name__`` attribute and attempt to find a mapping. Defaults to ``False``. :type default_to_str: :class:`bool <python:bool>` :param type_mapping: Determines how value types in ``serialized_dict`` map to SQL column data types. To add a new mapping or override a default, set a key to the name of the value type in Python, and set the value to a :doc:`SQLAlchemy Data Type <sqlalchemy:core/types>`. The following are the default mappings applied: .. list-table:: :widths: 30 30 :header-rows: 1 * - Python Literal - SQL Column Type * - ``bool`` - :class:`Boolean <sqlalchemy:sqlalchemy.types.Boolean>` * - ``str`` - :class:`Text <sqlalchemy:sqlalchemy.types.Text>` * - ``int`` - :class:`Integer <sqlalchemy:sqlalchemy.types.Integer>` * - ``float`` - :class:`Float <sqlalchemy:sqlalchemy.types.Float>` * - ``date`` - :class:`Date <sqlalchemy:sqlalchemy.types.Date>` * - ``datetime`` - :class:`DateTime <sqlalchemy:sqlalchemy.types.DateTime>` * - ``time`` - :class:`Time <sqlalchemy:sqlalchemy.types.Time>` :type type_mapping: :class:`dict <python:dict>` with type names as keys and column data types as values. :param base_model_attrs: Optional :class:`dict <python:dict>` of special attributes that will be applied to the generated :class:`BaseModel <sqlathanor.declarative.BaseModel>` (e.g. ``__table_args__``). Keys will correspond to the attribute name, while the value is the value that will be applied. Defaults to :obj:`None <python:None>`. :type base_model_attrs: :class:`dict <python:dict>` / :obj:`None <python:None>` :param kwargs: Any additional keyword arguments will be passed to :func:`declarative_base() <sqlathanor.declarative.declarative_base>` when generating the programmatic :class:`BaseModel <sqlathanor.declarative.BaseModel>`. :returns: :term:`Model class` whose structure matches ``serialized_dict``. :rtype: :class:`BaseModel` :raises UnsupportedValueTypeError: when a value in ``serialized_dict`` does not have a corresponding key in ``type_mapping`` :raises ValueError: if ``serialized_dict`` is not a :class:`dict <python:dict>` or is empty :raises ValueError: if ``tablename`` is empty :raises ValueError: if ``primary_key`` is empty """ # pylint: disable=too-many-branches if not isinstance(serialized_dict, dict): raise ValueError('serialized_dict must be a dict') if not serialized_dict: raise ValueError('serialized_dict cannot be empty') if not tablename: raise ValueError('tablename cannot be empty') if not primary_key: raise ValueError('primary_key cannot be empty') serialization_config = validate_serialization_config(serialization_config) GeneratedBaseModel = declarative_base(cls = cls, **kwargs) class InterimGeneratedModel(object): # pylint: disable=too-few-public-methods,missing-docstring,invalid-variable-name __tablename__ = tablename prospective_serialization_config = [] for key in serialized_dict: value = serialized_dict[key] column_type = get_type_mapping(value, type_mapping = type_mapping, skip_nested = skip_nested, default_to_str = default_to_str) if column_type is None: continue if key == primary_key: column = Column(name = key, type_ = column_type, primary_key = True) else: column = Column(name = key, type_ = column_type) setattr(InterimGeneratedModel, key, column) attribute_config = AttributeConfiguration(name = key, supports_csv = True, supports_json = True, supports_yaml = True, supports_dict = True, on_serialize = None, on_deserialize = None) prospective_serialization_config.append(attribute_config) if not serialization_config: serialization_config = prospective_serialization_config if base_model_attrs: for key in base_model_attrs: setattr(InterimGeneratedModel, key, base_model_attrs[key]) class GeneratedModel(GeneratedBaseModel, InterimGeneratedModel): # pylint: disable=missing-docstring,too-few-public-methods pass GeneratedModel.configure_serialization(configs = serialization_config) return GeneratedModel
[docs]def generate_model_from_json(serialized, tablename, primary_key, deserialize_function = None, cls = BaseModel, serialization_config = None, skip_nested = True, default_to_str = False, type_mapping = None, base_model_attrs = None, deserialize_kwargs = None, **kwargs): """Generate a :term:`model class` from a serialized :term:`JSON <JavaScript Object Notation (JSON)>` string. .. versionadded: 0.3.0 .. note:: This function *cannot* programmatically create :term:`relationships <relationship>`, :term:`hybrid properties <hybrid property>`, or :term:`association proxies <association proxy>`. :param serialized: The JSON data whose keys will be treated as column names, while value data types will determine :term:`model attribute` data types, or the path to a file whose contents will be the JSON object in question. .. note:: If providing a path to a file, and if the file contains more than one JSON object, will only use the first JSON object listed. :type serialized: :class:`str <python:str>` / Path-like object :param tablename: The name of the SQL table to which the model corresponds. :type tablename: :class:`str <python:str>` :param primary_key: The name of the column/key that should be used as the table's primary key. :type primary_key: :class:`str <python:str>` :param deserialize_function: Optionally override the default JSON deserializer. Defaults to :obj:`None <python:None>`, which calls the default :func:`simplejson.loads() <simplejson:simplejson.loads>` function from the doc:`simplejson <simplejson:index>` library. .. note:: Use the ``deserialize_function`` parameter to override the default JSON deserializer. A valid ``deserialize_function`` is expected to accept a single :class:`str <python:str>` and return a :class:`dict <python:dict>`, similar to :func:`simplejson.loads() <simplejson:simplejson.loads>`. If you wish to pass additional arguments to your ``deserialize_function`` pass them as keyword arguments (in ``deserialize_kwargs``). :type deserialize_function: callable / :obj:`None <python:None>` :param cls: The base class to use when generating a new :term:`model class`. Defaults to :class:`BaseModel` to provide serialization/de-serialization support. If a :class:`tuple <python:tuple>` of classes, will include :class:`BaseModel` in that list of classes to mixin serialization/de-serialization support. If not :obj:`None <python:None>` and not a :class:`tuple <python:tuple>`, will mixin :class:`BaseModel` with the value passed to provide serialization/de-serialization support. :type cls: :obj:`None <python:None>` / :class:`tuple <python:tuple>` of classes / class object :param serialization_config: Collection of :class:`AttributeConfiguration <sqlathanor.attributes.AttributeConfiguration>` that determine the generated model's :term:`serialization`/:term:`de-serialization` :ref:`configuration <configuration>`. If :obj:`None <python:None>`, will support serialization and de-serialization across all keys in ``serialized_dict``. Defaults to :obj:`None <python:None>`. :type serialization_config: Iterable of :class:`AttributeConfiguration <sqlathanor.attributes.AttributeConfiguration>` or coercable :class:`dict <python:dict>` objects / :obj:`None <python:None>` :param skip_nested: If ``True`` then any keys in ``serialized_json`` that feature nested items (e.g. iterables, JSON objects, etc.) will be ignored. If ``False``, will treat serialized items as :class:`str <python:str>`. Defaults to ``True``. :type skip_nested: :class:`bool <python:bool>` :param default_to_str: If ``True``, will automatically set a key/column whose value type cannot be determined to ``str`` (:class:`Text <sqlalchemy:sqlalchemy.types.Text>`). If ``False``, will use the value type's ``__name__`` attribute and attempt to find a mapping. Defaults to ``False``. :type default_to_str: :class:`bool <python:bool>` :param type_mapping: Determines how value types in ``serialized`` map to SQL column data types. To add a new mapping or override a default, set a key to the name of the value type in Python, and set the value to a :doc:`SQLAlchemy Data Type <sqlalchemy:core/types>`. The following are the default mappings applied: .. list-table:: :widths: 30 30 :header-rows: 1 * - Python Literal - SQL Column Type * - ``bool`` - :class:`Boolean <sqlalchemy:sqlalchemy.types.Boolean>` * - ``str`` - :class:`Text <sqlalchemy:sqlalchemy.types.Text>` * - ``int`` - :class:`Integer <sqlalchemy:sqlalchemy.types.Integer>` * - ``float`` - :class:`Float <sqlalchemy:sqlalchemy.types.Float>` * - ``date`` - :class:`Date <sqlalchemy:sqlalchemy.types.Date>` * - ``datetime`` - :class:`DateTime <sqlalchemy:sqlalchemy.types.DateTime>` * - ``time`` - :class:`Time <sqlalchemy:sqlalchemy.types.Time>` :type type_mapping: :class:`dict <python:dict>` with type names as keys and column data types as values. :param base_model_attrs: Optional :class:`dict <python:dict>` of special attributes that will be applied to the generated :class:`BaseModel <sqlathanor.declarative.BaseModel>` (e.g. ``__table_args__``). Keys will correspond to the attribute name, while the value is the value that will be applied. Defaults to :obj:`None <python:None>`. :type base_model_attrs: :class:`dict <python:dict>` / :obj:`None <python:None>` :param deserialize_kwargs: Optional additional keyword arguments that will be passed to the deserialize function. Defaults to :obj:`None <python:None>`. :type deserialize_kwargs: :class:`dict <python:dict>` / :obj:`None <python:None>` :param kwargs: Any additional keyword arguments will be passed to :func:`declarative_base() <sqlathanor.declarative.declarative_base>` when generating the programmatic :class:`BaseModel <sqlathanor.declarative.BaseModel>`. :returns: :term:`Model class` whose structure matches ``serialized``. :rtype: :class:`BaseModel` :raises UnsupportedValueTypeError: when a value in ``serialized`` does not have a corresponding key in ``type_mapping`` :raises ValueError: if ``tablename`` is empty """ # pylint: disable=line-too-long if deserialize_kwargs: from_json = parse_json(serialized, deserialize_function = deserialize_function, **deserialize_kwargs) else: from_json = parse_json(serialized, deserialize_function = deserialize_function) if isinstance(from_json, list): from_json = from_json[0] generated_model = generate_model_from_dict(from_json, tablename, primary_key, cls = cls, serialization_config = serialization_config, skip_nested = skip_nested, default_to_str = default_to_str, type_mapping = type_mapping, base_model_attrs = base_model_attrs, **kwargs) return generated_model
[docs]def generate_model_from_yaml(serialized, tablename, primary_key, deserialize_function = None, cls = BaseModel, serialization_config = None, skip_nested = True, default_to_str = False, type_mapping = None, base_model_attrs = None, deserialize_kwargs = None, **kwargs): """Generate a :term:`model class` from a serialized :term:`YAML <YAML Ain't a Markup Language (YAML)>` string. .. versionadded: 0.3.0 .. note:: This function *cannot* programmatically create :term:`relationships <relationship>`, :term:`hybrid properties <hybrid property>`, or :term:`association proxies <association proxy>`. :param serialized: The YAML data whose keys will be treated as column names, while value data types will determine :term:`model attribute` data types, or the path to a file whose contents will be the YAML object in question. :type serialized: :class:`str <python:str>` / Path-like object :param tablename: The name of the SQL table to which the model corresponds. :type tablename: :class:`str <python:str>` :param primary_key: The name of the column/key that should be used as the table's primary key. :type primary_key: :class:`str <python:str>` :param deserialize_function: Optionally override the default YAML deserializer. Defaults to :obj:`None <python:None>`, which calls the default ``yaml.safe_load()`` function from the `PyYAML <https://github.com/yaml/pyyaml>`_ library. .. note:: Use the ``deserialize_function`` parameter to override the default YAML deserializer. A valid ``deserialize_function`` is expected to accept a single :class:`str <python:str>` and return a :class:`dict <python:dict>`, similar to ``yaml.safe_load()``. If you wish to pass additional arguments to your ``deserialize_function`` pass them as keyword arguments (in ``kwargs``). :type deserialize_function: callable / :obj:`None <python:None>` :param cls: The base class to use when generating a new :term:`model class`. Defaults to :class:`BaseModel` to provide serialization/de-serialization support. If a :class:`tuple <python:tuple>` of classes, will include :class:`BaseModel` in that list of classes to mixin serialization/de-serialization support. If not :obj:`None <python:None>` and not a :class:`tuple <python:tuple>`, will mixin :class:`BaseModel` with the value passed to provide serialization/de-serialization support. :type cls: :obj:`None <python:None>` / :class:`tuple <python:tuple>` of classes / class object :param serialization_config: Collection of :class:`AttributeConfiguration <sqlathanor.attributes.AttributeConfiguration>` that determine the generated model's :term:`serialization`/:term:`de-serialization` :ref:`configuration <configuration>`. If :obj:`None <python:None>`, will support serialization and de-serialization across all keys in ``serialized_dict``. Defaults to :obj:`None <python:None>`. :type serialization_config: Iterable of :class:`AttributeConfiguration <sqlathanor.attributes.AttributeConfiguration>` or coercable :class:`dict <python:dict>` objects / :obj:`None <python:None>` :param skip_nested: If ``True`` then any keys in ``serialized_json`` that feature nested items (e.g. iterables, JSON objects, etc.) will be ignored. If ``False``, will treat serialized items as :class:`str <python:str>`. Defaults to ``True``. :type skip_nested: :class:`bool <python:bool>` :param default_to_str: If ``True``, will automatically set a key/column whose value type cannot be determined to ``str`` (:class:`Text <sqlalchemy:sqlalchemy.types.Text>`). If ``False``, will use the value type's ``__name__`` attribute and attempt to find a mapping. Defaults to ``False``. :type default_to_str: :class:`bool <python:bool>` :param type_mapping: Determines how value types in ``serialized`` map to SQL column data types. To add a new mapping or override a default, set a key to the name of the value type in Python, and set the value to a :doc:`SQLAlchemy Data Type <sqlalchemy:core/types>`. The following are the default mappings applied: .. list-table:: :widths: 30 30 :header-rows: 1 * - Python Literal - SQL Column Type * - ``bool`` - :class:`Boolean <sqlalchemy:sqlalchemy.types.Boolean>` * - ``str`` - :class:`Text <sqlalchemy:sqlalchemy.types.Text>` * - ``int`` - :class:`Integer <sqlalchemy:sqlalchemy.types.Integer>` * - ``float`` - :class:`Float <sqlalchemy:sqlalchemy.types.Float>` * - ``date`` - :class:`Date <sqlalchemy:sqlalchemy.types.Date>` * - ``datetime`` - :class:`DateTime <sqlalchemy:sqlalchemy.types.DateTime>` * - ``time`` - :class:`Time <sqlalchemy:sqlalchemy.types.Time>` :type type_mapping: :class:`dict <python:dict>` with type names as keys and column data types as values. :param base_model_attrs: Optional :class:`dict <python:dict>` of special attributes that will be applied to the generated :class:`BaseModel <sqlathanor.declarative.BaseModel>` (e.g. ``__table_args__``). Keys will correspond to the attribute name, while the value is the value that will be applied. Defaults to :obj:`None <python:None>`. :type base_model_attrs: :class:`dict <python:dict>` / :obj:`None <python:None>` :param deserialize_kwargs: Optional additional keyword arguments that will be passed to the deserialize function. Defaults to :obj:`None <python:None>`. :type deserialize_kwargs: :class:`dict <python:dict>` / :obj:`None <python:None>` :param kwargs: Any additional keyword arguments will be passed to :func:`declarative_base() <sqlathanor.declarative.declarative_base>` when generating the programmatic :class:`BaseModel <sqlathanor.declarative.BaseModel>`. :returns: :term:`Model class` whose structure matches ``serialized``. :rtype: :class:`BaseModel` :raises UnsupportedValueTypeError: when a value in ``serialized`` does not have a corresponding key in ``type_mapping`` :raises ValueError: if ``tablename`` is empty """ # pylint: disable=line-too-long if deserialize_kwargs: from_yaml = parse_yaml(serialized, deserialize_function = deserialize_function, **deserialize_kwargs) else: from_yaml = parse_yaml(serialized, deserialize_function = deserialize_function) if isinstance(from_yaml, list): from_yaml = from_yaml[0] generated_model = generate_model_from_dict(from_yaml, tablename, primary_key, cls = cls, serialization_config = serialization_config, skip_nested = skip_nested, default_to_str = default_to_str, type_mapping = type_mapping, base_model_attrs = base_model_attrs, **kwargs) return generated_model
[docs]def generate_model_from_csv(serialized, tablename, primary_key, cls = BaseModel, serialization_config = None, skip_nested = True, default_to_str = False, type_mapping = None, base_model_attrs = None, delimiter = '|', wrap_all_strings = False, null_text = 'None', wrapper_character = "'", double_wrapper_character_when_nested = False, escape_character = "\\", line_terminator = '\r\n', **kwargs): """Generate a :term:`model class` from a serialized :term:`CSV <Comma-Separated Value (CSV)>` string. .. versionadded: 0.3.0 .. note:: This function *cannot* programmatically create :term:`relationships <relationship>`, :term:`hybrid properties <hybrid property>`, or :term:`association proxies <association proxy>`. :param serialized: The CSV data whose column headers will be treated as column names, while value data types will determine :term:`model attribute` data types. .. note:: If a Path-like object, will read the file contents from a file that is assumed to include a header row. If a :class:`str <python:str>` and has more than one record (line), will assume the first line is a header row. If a :class:`list <python:list>`, will assume the first item is the header row. :type serialized: :class:`str <python:str>` / Path-like object / :class:`list <python:list>` :param tablename: The name of the SQL table to which the model corresponds. :type tablename: :class:`str <python:str>` :param primary_key: The name of the column/key that should be used as the table's primary key. :type primary_key: :class:`str <python:str>` :param cls: The base class to use when generating a new :term:`model class`. Defaults to :class:`BaseModel` to provide serialization/de-serialization support. If a :class:`tuple <python:tuple>` of classes, will include :class:`BaseModel` in that list of classes to mixin serialization/de-serialization support. If not :obj:`None <python:None>` and not a :class:`tuple <python:tuple>`, will mixin :class:`BaseModel` with the value passed to provide serialization/de-serialization support. :type cls: :obj:`None <python:None>` / :class:`tuple <python:tuple>` of classes / class object :param serialization_config: Collection of :class:`AttributeConfiguration <sqlathanor.attributes.AttributeConfiguration>` that determine the generated model's :term:`serialization`/:term:`de-serialization` :ref:`configuration <configuration>`. If :obj:`None <python:None>`, will support serialization and de-serialization across all keys in ``serialized_dict``. Defaults to :obj:`None <python:None>`. :type serialization_config: Iterable of :class:`AttributeConfiguration <sqlathanor.attributes.AttributeConfiguration>` or coercable :class:`dict <python:dict>` objects / :obj:`None <python:None>` :param skip_nested: If ``True`` then any keys in ``serialized_json`` that feature nested items (e.g. iterables, JSON objects, etc.) will be ignored. If ``False``, will treat serialized items as :class:`str <python:str>`. Defaults to ``True``. :type skip_nested: :class:`bool <python:bool>` :param default_to_str: If ``True``, will automatically set a key/column whose value type cannot be determined to ``str`` (:class:`Text <sqlalchemy:sqlalchemy.types.Text>`). If ``False``, will use the value type's ``__name__`` attribute and attempt to find a mapping. Defaults to ``False``. :type default_to_str: :class:`bool <python:bool>` :param type_mapping: Determines how value types in ``serialized`` map to SQL column data types. To add a new mapping or override a default, set a key to the name of the value type in Python, and set the value to a :doc:`SQLAlchemy Data Type <sqlalchemy:core/types>`. The following are the default mappings applied: .. list-table:: :widths: 30 30 :header-rows: 1 * - Python Literal - SQL Column Type * - ``bool`` - :class:`Boolean <sqlalchemy:sqlalchemy.types.Boolean>` * - ``str`` - :class:`Text <sqlalchemy:sqlalchemy.types.Text>` * - ``int`` - :class:`Integer <sqlalchemy:sqlalchemy.types.Integer>` * - ``float`` - :class:`Float <sqlalchemy:sqlalchemy.types.Float>` * - ``date`` - :class:`Date <sqlalchemy:sqlalchemy.types.Date>` * - ``datetime`` - :class:`DateTime <sqlalchemy:sqlalchemy.types.DateTime>` * - ``time`` - :class:`Time <sqlalchemy:sqlalchemy.types.Time>` :type type_mapping: :class:`dict <python:dict>` with type names as keys and column data types as values. :param base_model_attrs: Optional :class:`dict <python:dict>` of special attributes that will be applied to the generated :class:`BaseModel <sqlathanor.declarative.BaseModel>` (e.g. ``__table_args__``). Keys will correspond to the attribute name, while the value is the value that will be applied. Defaults to :obj:`None <python:None>`. :type base_model_attrs: :class:`dict <python:dict>` / :obj:`None <python:None>` :param delimiter: The delimiter used between columns. Defaults to ``|``. :type delimiter: :class:`str <python:str>` :param wrapper_character: The string used to wrap string values when wrapping is applied. Defaults to ``'``. :type wrapper_character: :class:`str <python:str>` :param null_text: The string used to indicate an empty value if empty values are wrapped. Defaults to `None`. :type null_text: :class:`str <python:str>` :param kwargs: Any additional keyword arguments will be passed to :func:`declarative_base() <sqlathanor.declarative.declarative_base>` when generating the programmatic :class:`BaseModel <sqlathanor.declarative.BaseModel>`. :returns: :term:`Model class` whose structure matches ``serialized``. :rtype: :class:`BaseModel` :raises UnsupportedValueTypeError: when a value in ``serialized`` does not have a corresponding key in ``type_mapping`` :raises ValueError: if ``tablename`` is empty :raises DeserializationError: if ``serialized`` is not a valid :class:`str <python:str>` :raises CSVStructureError: if there are less than 2 (two) rows in ``serialized`` or if column headers are not valid Python variable names """ # pylint: disable=line-too-long,too-many-arguments if not checkers.is_file(serialized): serialized = read_csv_data(serialized, single_record = False) from_csv = parse_csv(serialized, delimiter = delimiter, wrap_all_strings = wrap_all_strings, null_text = null_text, wrapper_character = wrapper_character, double_wrapper_character_when_nested = double_wrapper_character_when_nested, escape_character = escape_character, line_terminator = line_terminator) generated_model = generate_model_from_dict(from_csv, tablename, primary_key, cls = cls, serialization_config = serialization_config, skip_nested = skip_nested, default_to_str = default_to_str, type_mapping = type_mapping, base_model_attrs = base_model_attrs, **kwargs) return generated_model