@classmethod
def create(cls, default=None, *args, **kwargs):
    """Create a model instance.

        :param default: The data structure that will be used to store the model state.
        :param \\*\\*kwargs: Any model attribute can be initialized with the matching keyword.

        :return: The newly created model.

        >>> class Cowboy(sheraf.Model):
        ...    table = "cowboy"
        ...    name = sheraf.SimpleAttribute(default="John Doe")
        ...
        >>> with sheraf.connection(commit=True):
        ...    cowboy = Cowboy.create()
        ...    assert "John Doe" == cowboy.name
        ...
        ...    cowboy = Cowboy.create(name="George Abitbol")
        ...    assert "George Abitbol" == cowboy.name
        ...
        ...    Cowboy.create(this_attribute_does_not_exist="something") #  raises a TypeError
        Traceback (most recent call last):
            ...
        TypeError: TypeError: create() got an unexpected keyword argument 'this_attribute_does_not_exist'

        The function can also create sub-models recursively:

        >>> class Horse(sheraf.InlineModel):
        ...     name = sheraf.SimpleAttribute()
        ...
        >>> class Cowboy(sheraf.Model):
        ...     table = "cowboy"
        ...     name = sheraf.SimpleAttribute(default="John Doe")
        ...     horse = sheraf.InlineModelAttribute(Horse)
        ...
        >>> with sheraf.connection():
        ...     cowboy = Cowboy.create(name="George Abitbol", horse={"name": "Jolly Jumper"})
        ...     cowboy.horse.name
        'Jolly Jumper'
        """
    mapping = (default or cls.default_mapping)()
    model = cls._decorate(mapping)
    for attribute, value in kwargs.items():
        if attribute not in model.attributes:
            raise TypeError(
                "TypeError: create() got an unexpected keyword argument '{}'"
                .format(attribute))
        model.__setattr__(attribute, value)
    for name, attribute in model.attributes.items():
        if not attribute.lazy and name not in kwargs:
            model.__setattr__(name, attribute.create(model))
    return model
