Issue #39 new

Bug in django introspect

Afsoon Afzal
created an issue

When using model inheritance, if foreign key appeared in the parent model makes trouble. The patch to fix it is attached.

Comments (6)

  1. Kirill Simonov

    Sorry for being late with a reply.

    Could you attach an example that reproduces the problem (under Django 1.5.5)? I can't figure it out -- it seems to work even if I inherit one model from another.

    Also, I don't see how your patch could work: if Field objects are identical, surely Field.model objects are also identical, so a key `(field, field.model) is not functionally different from field.

  2. Afsoon Afzal reporter

    Hi,

    here is an example:

    class Transaction(models.Model):
    
        from_account = models.ForeignKey(Account, related_name='%(class)s_outcomes', on_delete=models.PROTECT)
    
    class Purchase(CachingMixin, Transaction):
        ....
    
    class OnlineBankPayment(Transaction):
       ....
    

    In this scenario, column_by_field[from_account] will be overwritten by every child of Transaction.

  3. Kirill Simonov

    Still can't reproduce it. Here's my models.py:

    from django.db import models
    
    class Account(models.Model):
        pass
    
    class Transaction(models.Model):
        from_account = models.ForeignKey(Account)
    
    class Purchase(Transaction):
        pass
    
    class OnlineBankPayment(Transaction):
        pass
    

    It works just fine for me with HTSQL and tweak.django. Moreover, Djando doesn't even create duplicate fields for my models; here's the schema it generates:

    CREATE TABLE "account_account" (
        "id" integer NOT NULL PRIMARY KEY
    );
    CREATE TABLE "account_transaction" (
        "id" integer NOT NULL PRIMARY KEY,
        "from_account_id" integer NOT NULL REFERENCES "account_account" ("id")
    );
    CREATE TABLE "account_purchase" (
        "transaction_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "account_transaction" ("id")
    );
    CREATE TABLE "account_onlinebankpayment" (
        "transaction_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "account_transaction" ("id")
    );
    
  4. synotna

    I am trying to add htsql-django to an existing django project, which uses django-guardian

    I think I am encountering the same bug, it fails on starting up during introspection:

    Traceback (most recent call last):
      File "/home/tech/.pycharm_helpers/pydev/pydevd.py", line 1532, in <module>
        debugger.run(setup['file'], None, None)
      File "/home/tech/.pycharm_helpers/pydev/pydevd.py", line 1143, in run
        pydev_imports.execfile(file, globals, locals) #execute the script
      File "/home/tech/esldj/all-in-one/manage.py", line 10, in <module>
        execute_from_command_line(sys.argv)
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/django/core/management/__init__.py", line 399, in execute_from_command_line
        utility.execute()
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/django/core/management/__init__.py", line 392, in execute
        self.fetch_command(subcommand).run_from_argv(self.argv)
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/django/core/management/base.py", line 242, in run_from_argv
        self.execute(*args, **options.__dict__)
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/django/core/management/base.py", line 280, in execute
        translation.activate('en-us')
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/django/utils/translation/__init__.py", line 130, in activate
        return _trans.activate(language)
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/django/utils/translation/trans_real.py", line 188, in activate
        _active.value = translation(language)
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/django/utils/translation/trans_real.py", line 177, in translation
        default_translation = _fetch(settings.LANGUAGE_CODE)
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/django/utils/translation/trans_real.py", line 159, in _fetch
        app = import_module(appname)
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/django/utils/importlib.py", line 40, in import_module
        __import__(name)
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/htsql_django/__init__.py", line 13, in <module>
        instance = HTSQL(None, CONFIG, DEFAULT_CONFIG)
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/htsql/core/application.py", line 183, in __init__
        addon.validate()
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/htsql/core/__init__.py", line 79, in validate
        introspect()
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/htsql/core/cache.py", line 43, in wrapper
        value = service(*args, **kwds)
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/htsql/core/introspect.py", line 85, in introspect
        catalog = Introspect.__invoke__()
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/htsql/core/adapter.py", line 284, in __invoke__
        return instance()
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/htsql/core/introspect.py", line 39, in IntrospectCleanup.__call__
        catalog = super(IntrospectCleanup, self).__call__()
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/htsql/tweak/django/introspect.py", line 76, in DjangoIntrospect.__call__
        table.add_foreign_key([column], target_table, [target_column])
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/htsql/core/entity.py", line 255, in add_foreign_key
        is_partial)
      File "/home/tech/.pyenv/versions/esldj-all-in-one-2.7.6/lib/python2.7/site-packages/htsql/core/entity.py", line 455, in __init__
        assert all(column.table is origin for column in origin_columns)
    AssertionError
    
    origin = guardian_userobjectpermission
    origin_columns = [<MutableColumnEntity guardian_groupobjectpermission.permission_id>]
    self = Unable to get repr for <class 'htsql.core.entity.MutableForeignKeyEntity'>
    target = auth_permission
    
  5. Log in to comment