1

I've looked at several answers to similar questions, and none of them fit my use case. That said, I apologize in advance if I've somehow missed the answer and this ends up being a re-posted question.

In short, I'm writing a small extension / wrapper around a legacy application that uses BDE Paradox tables as its backend. I can't change the backend, and the legacy application isn't being replaced any time soon. I can, however, access the backend and do everything I need to in SQLAlchemy using the Paradox ODBC drivers that ship with Windows.

The original creator of the legacy application organized the "database" for customer information as a series of ~28 individual Paradox DB files which all have an identical schema / design, but are named differently based on the first letter of the last name of the customer(s) they contain. As an example, the customer record for Adam Smith would be in the DB named [CUSTOMER_S], whereas the record for Johnny Appleseed would be in the DB named [CUSTOMER_A]. To further complicate things, the internal organization of the legacy application's file structure is such that (while all of the application's files exist in a single directory), the main application data is located in one folder and the customer data is located in another. The structure looks something like this:

-- /
  |
  -- Top-Level Application Directory
    |
    -- Main Application Data
      |
       ...
      |
    -- Customer Data
      |
       ...

While this is irritating, handling it is as simple as:

item_engine = create_engine(item_connection_string)
customer_engine = create_engine(customer_connection_string)

super_session = scoped_session(
    sessionmaker(binds={Item: item_engine, Customer: customer_engine})
)

super_session.configure(autoflush=False, autocommit=False, expire_on_commit=True)
session = super_session()

There are some strange internal rules in the legacy application that determine how items are matched to customers, but that's probably not germane to the question at hand.

What I'd like to do is something like this:

from sqlalchemy import event
from sqlalchemy.orm.query import Query

@event.listens_for(Query, "before_compile", named=True, retval=True)
def fix_customer_tables(query: Query, *args, **kwargs):

    # Check if the object being queried is a Customer
    # If so, alter the __tablename__ before it's passed
    # to the SQLAlchemy compiler so that the record is
    # pulled from or written to the correct file

    return query

What's got me completely turned around is trying to figure out where / how the Query object that gets passed into the fix_customer_tables listener actually stores / references the __tablename__ to be queried. If someone could point me in the right direction, that would be amazing.

  • I don't know if you can tag people who haven't yet commented on a question, but hopefully @zzzeek is around, sees this, and is willing to steer me where I need to go. – Mark Schlachter Jul 30 '20 at 19:39
  • *"I don't know if you can tag people who haven't yet commented on a question"* - I'm pretty sure you can't. At least you *couldn't*, and I don't think that has changed. Mike does not follow SO any more, but he does keep an eye on [GitHub issues](https://github.com/sqlalchemy/sqlalchemy/issues). – Gord Thompson Jul 30 '20 at 21:26
  • @GordThompson Ah. There you go again, being awesome I'd be happy to open an issue, but that just seemed... excessive? It's not *really* an *issue* per se, it's more of an... esoteric use case that I'm confused about? If you think I should open an issue though, I absolutely will. – Mark Schlachter Jul 30 '20 at 22:27
  • The other place you could try is the [mailing list](https://www.sqlalchemy.org/support.html#mailinglist). I don't follow it myself, but quite a few knowledgeable people do. Perhaps try that first, and if you don't get an answer here or there then if you post an issue on GitHub one of us will tag it as a "question". – Gord Thompson Jul 30 '20 at 22:34
  • @GordThompson I opened [an issue](https://github.com/sqlalchemy/sqlalchemy/issues/5487#issue-669953723) on the main SQLAlchemy GitHub repo, tagged as a question. I did some experimenting between last night and today, so there's a bit of extra context there – Mark Schlachter Jul 31 '20 at 15:50

0 Answers0