Ticket #105 (accepted enhancement)

Opened 3 years ago

Last modified 3 years ago

Allow ManyToMany to specify a manually-defined table through a string argument

Reported by: guest Owned by: ged
Priority: normal Milestone:
Component: core Version: 0.7.1
Keywords: Cc:

Description

See attached script. ManyToMany relationship using a custom table to represent the association fails with an AssertionError:

Traceback (most recent call last):

File "elixir1.py", line 24, in <module>

setup_all()

File "/home/miv/.virtualenvs2.5/sqlalchemy_0_6_support_new/lib/python2.5/site-packages/Elixir-0.7.1-py2.5.egg/elixir/init.py", line 94, in setup_all

setup_entities(entities)

File "/home/miv/.virtualenvs2.5/sqlalchemy_0_6_support_new/lib/python2.5/site-packages/Elixir-0.7.1-py2.5.egg/elixir/entity.py", line 951, in setup_entities

method()

File "/home/miv/.virtualenvs2.5/sqlalchemy_0_6_support_new/lib/python2.5/site-packages/Elixir-0.7.1-py2.5.egg/elixir/entity.py", line 312, in setup_reltables

self.call_builders('create_tables')

File "/home/miv/.virtualenvs2.5/sqlalchemy_0_6_support_new/lib/python2.5/site-packages/Elixir-0.7.1-py2.5.egg/elixir/entity.py", line 481, in call_builders

getattr(builder, what)()

File "/home/miv/.virtualenvs2.5/sqlalchemy_0_6_support_new/lib/python2.5/site-packages/Elixir-0.7.1-py2.5.egg/elixir/relationships.py", line 910, in create_tables

self.inverse.table is self.table

AssertionError

Elixir 0.7.1 SQLAlchemy 0.6 beta (trunk r6633)

This relationship seemed to work okay with Elixir 0.6.1.

Attachments

elixir1.py (0.8 kB) - added by guest 3 years ago.

Change History

Changed 3 years ago by guest

  Changed 3 years ago by guest

Updated SQLAlchemy to r6663 but it's still broke.

  Changed 3 years ago by guest

  • version set to 0.7.1

Further investigation suggests this has to do with the order that things are defined. If I define the document_sharers table first then everything seems to work. If it's created in between the other two tables then it goes nuts.

If the table attribute is changed to a string in both Entities then it seems to work, but in our code it causes other problems. Namely, somewhere in the guts of SQLAlchemy it fails to compile the mapper claiming "'str' object has no attribute 'foreign_keys'".

follow-up: ↓ 4   Changed 3 years ago by guest

Okay, this seems to work if you define document_sharers first and then pass the document_sharers table object into both ManyToMany definitions. That's probably how it was designed in which case maybe all you have to do is update the documentation to explain that the argument to table= MUST be a SQLAlchemy Table object and make is assert and die if a string is passed in.

in reply to: ↑ 3   Changed 3 years ago by ged

  • owner set to ged
  • status changed from new to accepted
  • type changed from defect to enhancement
  • summary changed from ManyToMany rel with custom table broken with Elixir 0.7.1, SQLAlchemy 0.6 to Allow ManyToMany to specify a manually-defined table through a string argument

Replying to guest:

Okay, this seems to work if you define document_sharers first and then pass the document_sharers table object into both ManyToMany definitions. That's probably how it was designed in which case maybe all you have to do is update the documentation to explain that the argument to table= MUST be a SQLAlchemy Table object and make is assert and die if a string is passed in.

This is indeed how it was designed to be used. We could make it work with strings too, but I fear people would get confused about the difference between a string "table" argument and the "tablename" argument. And we can't use the tablename argument for that because that would ambiguous: do you want to create a new table object with that name or look up in the metadata for that name? And looking the metadata up then creating the table if not found seems like it could produce surprising behavior. Adding a new argument like "create=True" would work, but is inelegant and might be confusing too. Any idea how to get it right?

In the mean time, I've updated the doc in r522.

Note: See TracTickets for help on using tickets.