Skip to main content

It converts django models to a sqlalchemy orm/expression objects.

Project description

https://circleci.com/gh/righ/d2a.svg?style=svg

It converts django models to sqlalchemy orm/expression objects.

Requirements

  • Python: 2.7, 3.3, 3.4, 3.5, 3.6 (Tested with 2.7, 3.6)

  • Django: 1.9 ~ 2.0 (Tested with 1.11, 2.0)

  • SQLAlchemy: 0.9 ~ 1.2 (Tested with 1.2)

Installation

$ pip install d2a

Usage

altogether

Example: you make models_sqla.py at the same directory which models.py has been placed on.

That’s all, you can import sqlalchemy declaration made from django model.

>>> from books import models
>>> models.  # tab completion
models.ArrayField(        models.Book(              models.CategoryRelation(  models.models
models.Author(            models.Category(          models.JSONField(         models.uuid

>>> models.Book
<class 'books.models.Book'>

>>> models.Book.
models.Book.DoesNotExist(             models.Book.delete(                   models.Book.refresh_from_db(
models.Book.MultipleObjectsReturned(  models.Book.description               models.Book.sales
models.Book.add_to_class(             models.Book.from_db(                  models.Book.save(
models.Book.author                    models.Book.full_clean(               models.Book.save_base(
models.Book.author_id                 models.Book.get_deferred_fields(      models.Book.serializable_value(
models.Book.category                  models.Book.id                        models.Book.tags
models.Book.check(                    models.Book.mro(                      models.Book.title
models.Book.clean(                    models.Book.objects                   models.Book.unique_error_message(
models.Book.clean_fields(             models.Book.pk                        models.Book.validate_unique(
models.Book.content                   models.Book.prepare_database_save(
models.Book.date_error_message(       models.Book.price
>>> from books import models_sqla
>>> models_sqla.  # tab completion
models_sqla.Author(            models_sqla.BookCategory(      models_sqla.CategoryRelation(  models_sqla.transfer(
models_sqla.Book(              models_sqla.Category(          models_sqla.models

>>> models_sqla.Book
<class 'd2a.book'>

>>> models_sqla.Book.  # tab completion
models_sqla.Book.author       models_sqla.Book.content      models_sqla.Book.metadata     models_sqla.Book.tags
models_sqla.Book.author_id    models_sqla.Book.description  models_sqla.Book.mro(         models_sqla.Book.title
models_sqla.Book.category     models_sqla.Book.id           models_sqla.Book.price
# SQL Expression schema
>>> models_sqla.Book.__table__
Table(
  'book', MetaData(bind=None),
  Column('id', UUID(), table=<book>, primary_key=True, nullable=False, default=ColumnDefault(<function uuid4 at 0x7f3cebe7e598>)),
  Column('price', JSON(astext_type=Text()), table=<book>, nullable=False, default=ColumnDefault(<function NOT_PROVIDED at 0x7f3cebe7ebf8>)),
  Column('title', VARCHAR(length=255), table=<book>, nullable=False, default=ColumnDefault(<function NOT_PROVIDED at 0x7f3cebe7ec80>)),
  Column('description', TEXT(), table=<book>, default=ColumnDefault(<function NOT_PROVIDED at 0x7f3cebe7ed08>)),
  Column('author_id', INTEGER(), ForeignKey('author.id'), table=<book>, default=ColumnDefault(<function NOT_PROVIDED at 0x7f3cebe7ed90>)),
  Column('content', BYTEA(), table=<book>, nullable=False, default=ColumnDefault(<function NOT_PROVIDED at 0x7f3cebe7ee18>)),
  Column('tags', ARRAY(VARCHAR()), table=<book>, nullable=False, default=ColumnDefault(<function NOT_PROVIDED at 0x7f3cebe7eea0>)),
  schema=None
)

Also, it can extract model declared implicitly depending on m2m field. (in this case, BookCategory)

single

If you just want to convert one model, you should use declare function

>>> from d2a import declare
>>> from sales.models import Sales
>>> sales = declare(Sales)
>>> sales
<class 'd2a.sales'>

>>> sales.__table__
Table(
  'sales', MetaData(bind=None),
  Column('id', BIGINT(), table=<sales>, primary_key=True, nullable=False, default=ColumnDefault(<function NOT_PROVIDED at 0x7f3cebdebf28>)),
  Column('book_id', UUID(), ForeignKey('book.id'), table=<sales>, nullable=False, default=ColumnDefault(<function NOT_PROVIDED at 0x7f3cebdebea0>)),
  Column('sold', TIMESTAMP(), table=<sales>, nullable=False, default=ColumnDefault(<function NOT_PROVIDED at 0x7f3cebdeb730>)),
  Column('reservation', INTERVAL(), table=<sales>, default=ColumnDefault(<function NOT_PROVIDED at 0x7f3cebdeb6a8>)),
  Column('source', INET(), table=<sales>, default=ColumnDefault(<function NOT_PROVIDED at 0x7f3cebdeb620>)),
  schema=None
)

>>> sales.
sales.book         sales.id           sales.mro(         sales.sold
sales.book_id      sales.metadata     sales.reservation  sales.source

Custom fields

If you are using customized field which is not built-in, you can register the field as the other field using alias method.

from django.db.models import ImageField

class ExtendedImageField(ImageField):
    """something customizing"""

from d2a import alias
alias(ExtendedImageField, ImageField)

Demo

start up environment

$ git clone git@github.com:righ/d2a.git
$ cd d2a
$ docker-compose up

preparation

$ docker exec -it d2a_app_1 /bin/bash
# python -m venv venv # only first time
# source venv/bin/activate
(venv) # cd project_postgresql/ # (or mysql)
(venv) project_postgresql # ./manage.py migrate

execute

(venv) project_postgresql # ./manage.py shell
>>> from books import models_sqla
>>> book = models_sqla.Book()
>>> author = models_sqla.Author()
>>> book.author = author
>>> author.books
[<d2a.book object at 0x7f3cec539358>]
# And do something you want do ;)

History

1.0.1:
  • (2018-07-06)

  • Fixed a bug, that it will be provided None even though it does not be specified default argument.

1.0.0:
  • (2018-07-05)

  • Fixed bugs.

  • Added unit tests.

0.0.6:
  • Fixed a bug that abstract models become the targets.

  • Deleted install_requires.

0.0.5:
  • added alias method.

0.0.4:
  • fixed bugs.

0.0.3:
  • it got easy to declare custom field.

  • transfer method can define secondary table.

0.0.2:
  • it supported m2m field.

  • it limited django version less than 1.9.

0.0.1:

first release (2017-12-27)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

d2a-1.0.1.tar.gz (7.8 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page