Code generation

Back to doc index

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}]

Warning

  • 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

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 }}

..warning:

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.