:date: 2019-01-08

========================
Tuesday, January 8, 2019
========================

Lino under Python 3
===================

I repaired `some failures under Python 3
<https://travis-ci.org/lino-framework/book/jobs/476490532>`__.
Two of them were easy:

- 2019-01-08 10:42 in *book*:
  `6d5089f <https://github.com/lino-framework/book/commit/12531ec9edafc1eaefa503aa26f13bf2f6d5089f>`__
  (http://luc.lino-framework.org/blog/2019/0108.html)

But a third one is more trick:
:message:`SQLite schema editor cannot be used while foreign key constraint
checks are enabled. Make sure to disable them before entering a
transaction.atomic() context because SQLite3 does not support disabling them in
the middle of a multi-statement transaction.`.

The problem occurs only when using Django 2.1.5, not with Django 2.1.4.

https://docs.djangoproject.com/en/5.2//releases/2.1.5/

It is a side effect of Django ticket 30023:
https://code.djangoproject.com/ticket/30023

The `source code
<https://github.com/django/django/blob/master/django/db/backends/sqlite3/schema.py>`__ says::

        if not self.connection.disable_constraint_checking():

TODO: investigate more, maybe write a problem report.

Lino and Django migrations
==========================

Yes of course :cmd:`pm prep` uses the `--run-syncdb
<https://docs.djangoproject.com/en/5.2//ref/django-admin/#cmdoption-migrate-run-syncdb>`__
option.  Because Lino doesn't use Django migrations.

I understood this as an impulse to dive once more into :ticket:`2322` (Django
migrations with Lino). One problem was that choicelist fields are custom
fields and so we must explain Django how to migrate them.
I did some changes in the
:mod:`lino.core.choicelists`
and now probably fixed the problem.  At least :manage:`makemigrations` now works::

    $ go tera1
    $ dm makemigrations tera

Output::

  Migrations for 'tera':
  .../lino_tera/lib/tera/migrations/0001_initial.py
    - Create model Client
    - Create model LifeMode
    - Create model Procurer
    - Add field life_mode to client
    - Add field nationality to client
    - Add field obsoletes to client
    - Add field user to client

Or the same with contacts::

    $ dm makemigrations contacts
    Migrations for 'contacts':
      .../lino_tera/lib/contacts/migrations/0001_initial.py
        - Create model CompanyType
        - Create model Partner
        - Create model Role
        - Create model RoleType
        - Create model Company
        - Create model Person
        - Add field type to role
        - Add field city to partner
        - Add field client_contact_type to partner
        - Add field country to partner
        - Add field payment_term to partner
        - Add field purchase_account to partner
        - Add field region to partner
        - Add field company to role
        - Add field person to role

Note that above does not work under Python 2. Under Python 2 the resulting
migration files are invalid.  If I make the migrations for the second plugin, I
get a SyntaxError when that operation tries to import the generated files of
the first.  For example::

    Traceback (most recent call last):
      File "manage.py", line 7, in <module>
        execute_from_command_line(sys.argv)
      ...
      File "/media/dell1tb/work/tera/lino_tera/lib/contacts/migrations/0001_initial.py", line 50
        ('language', lino.utils.mldbc.fields.LanguageField(blank=True, choices=[(en', 'English'), (de', 'German'), (fr', 'French')], help_text='The language to use when communicating with this partner.', max_length=5, verbose_name='Language')),
                                                                                      ^
    SyntaxError: invalid syntax


Of courses the ``choices=[(en', 'English'), (de', 'German'), (fr', 'French')]``
in above example is an invalid syntax.

I currently suspect the str of the future package of disturbing Django: Django
tries to artificially remove the ``u`` prefixes from string literals but does
not know that there is a future package which simulates Python 3 strings.