AnswerDotAI / sqlite-minutils

A fork of sqlite-utils with CLI etc removed
https://AnswerDotAI.github.io/sqlite-minutils
Apache License 2.0
6 stars 6 forks source link

Support list foreign keys in `db.t.create()` #6

Closed minki-j closed 1 month ago

minki-j commented 1 month ago

ISSUE

When the cache decorator checks if a set of parameters used for a function is processed before, it only allows hashable parameters. Thus, when foreign_keys parameter is passed with a List value, the decorator throws an error:

  File "/Users/minkijung/anaconda3/envs/gitmeetup/lib/python3.12/site-packages/fastlite/kw.py", line 88, in create
    return self._orig_create(
           ^^^^^^^^^^^^^^^^^^
  File "/Users/minkijung/anaconda3/envs/gitmeetup/lib/python3.12/site-packages/sqlite_minutils/db.py", line 1619, in create
    self.db.create_table(
  File "/Users/minkijung/anaconda3/envs/gitmeetup/lib/python3.12/site-packages/sqlite_minutils/db.py", line 983, in create_table
    created_table = self.table(
                    ^^^^^^^^^^^
TypeError: unhashable type: 'list'

SOLUTION

I've added another decorator convert_lists_to_tuples to address this issue.

    def convert_lists_to_tuples(function):
        def wrapper(*args, **kwargs):
            args = tuple(tuple(arg) if isinstance(arg, list) else arg for arg in args)
            kwargs = {k: tuple(v) if isinstance(v, list) else v for k, v in kwargs.items()}
            result = function(*args, **kwargs)
            return tuple(result) if isinstance(result, list) else result
        return wrapper

TEST

To test this PR, follow the instruction below:

  1. create two tables where the second table reference the first table's id as FK
    
    from fasthtml.common import *

db = database("data/main.db")

users, readmes = ( db.t.users, db.t.readmes, )

users.create( id=str, name=str, pk="id", ) readmes.create( id=str, user_id=str, pk="id", foreign_keys=[("user_id", "users")], )


2. Check the error I mentioned above occurs. 
3. Try with the newly added decorator and make sure the error disappears. 
minki-j commented 1 month ago

@jph00 Please review the PR.

jph00 commented 1 month ago

Nice solution!