d2a
features
Codegen

Code generation

Manually defining SQLAlchemy in the same way as Django models is bothersome, and the definitions may diverge when changes occur.

d2a makes a sqlalchemy models file from all django models on your behalf.

Just use django command sqla_codegen. It will be available after the installation.

$ python manage.py sqla_codegen [--path={output path}] [--template-path={template path}] [--db-type={database type}]

  • Do not use with Auto loading.
  • AUTOLOAD is normally disabled but gets enabled when set dict object to settings.D2A_CONFIG["AUTOLOAD"].

Example

Command options

All options are optional.

  • --path:

    The file will be stored into this path.

    By default d2a makes a models_sqla.py at your django project root.

  • --template-path:

    To make it versatile, d2a allows the developer to customize template. Specify the relative file path from settings.TEMPLATES

    Current original template is here (opens in a new tab)

    Example:

    You can get also schemas from Table suffix like the following:

     
    # Code generated by d2a (https://github.com/walkframe/d2a).
    # `{{ command }}` at {{ generated_at }}.
      
    {{ blocks.before_importing }}
    from importlib import import_module
      
    import sqlalchemy as sa
    from sqlalchemy import types as default_types
    from sqlalchemy.dialects import (
        postgresql as postgresql_types,
        mysql as mysql_types,
        oracle as oracle_types,
    )
    from sqlalchemy.ext.declarative import declarative_base
    try:
        from geoalchemy2 import types as geotypes
    except ImportError:
        pass
      
    {{ blocks.after_importing }}
      
    Base = declarative_base()
      
      
    class CIText(default_types.String):
        '''DO NOT DELETE THIS CLASS'''
        __visit_name__ = 'CITEXT'
      
      
    def GET_DEFAULT(path):
        '''DO NOT DELETE THIS FUNCTION'''
      
        module_path, model_name, field_name = path.rsplit(".", 2)
        try:
            module = import_module(module_path)
            model = getattr(module, model_name)
        except (ImportError, AttributeError):
            return None
     
        for field in model._meta.fields:
            if field.name == field_name:
                return field.default
      
      
    {{ blocks.before_models }}
      
      
    {% for model in models %}
    class {{ model.model_name }}(Base):
        __tablename__ = '{{ model.table_name }}'
        {% for name, args in model.columns.items %}
        {{ name }} = sa.Column({% for arg in args %}
            {{ arg | safe }},{% endfor %}
        ){% endfor %}{% for name, args in model.relationships.items %}
        {{ name }} = sa.orm.relationship({% for arg in args %}
            {{ arg | safe }},{% endfor %}
        ){% endfor %}
      
      
    {{ model.model_name }}Table = {{ model.model_name }}.__table__
    {% endfor %}
    {{ blocks.after_models }}

    Deleting CIText and GET_DEFAULT is prohibited.

  • --db-type:

    You can select a type of database, it affects sqlalchemy field types of models.

    Available options:

    • default
    • postgresql
    • mysql
    • oracle

    When you do not specify this option, d2a will judge the type from django settings automatically. So you do not have to specify this option usually.