Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImportError when pypika is also installed #6

Open
jorenham opened this issue Sep 29, 2022 · 2 comments
Open

ImportError when pypika is also installed #6

jorenham opened this issue Sep 29, 2022 · 2 comments

Comments

@jorenham
Copy link

When pypika and pypika-tortoise are both installed, both are installed within the same site-packages directory (see #5). This causes an ImportError, because dialects/__init__.py is imported by upstream pypika's __init__.py, instead of its own dialects.py:

File "/myproject/.venv/lib/python3.10/site-packages/tortoise/__init__.py", line 11, <module>
from pypika import Table
File "/myproject/.venv/lib/python3.10/site-packages/pypika/__init__.py", line 34, <module>
from pypika.dialects import (

dialects: <module 'pypika.dialects' from '/myproject/.venv/lib/python3.10/site-packages/pypika/dialects/__init__.py'>

ImportError:
cannot import name 'ClickHouseQuery' from 'pypika.dialects' (/myproject/.venv/lib/python3.10/site-packages/pypika/dialects/__init__.py)

Please rename this package.

And if you've watched "the Fly", you'll know the disastrous consequences of merging two species 😉 .

@waketzheng
Copy link
Contributor

Before the issue fixed, you can manually rename pypika to pypika_tortoise and update import lines in tortoise by the following script:

  • rename.py
#!/usr/bin/env python
import shutil
import subprocess
import sys
from pathlib import Path

try:
    import tortoise
except ImportError as e:
    raise Exception("You may need to activate virtual environment first!") from e
else:
    import pypika


def pip_install(package, *args) -> None:
    command = [sys.executable, "-m", "pip", "install", package, *args]
    print("-->", *command)
    subprocess.run(command)


try:
    from pypika.dialects import ClickHouseQuery  # type:ignore
except ImportError:
    # pypika-tortoise installed
    pass
else:
    assert ClickHouseQuery
    # Install pypika-tortoise to replace pypika
    pip_install("pypika-tortoise", "--force-reinstall")


def migrate(src_dir: Path) -> None:
    count = 0
    for p in src_dir.rglob("*.py"):
        s = p.read_text("utf-8")
        src, dst = "from pypika", "from pypika_tortoise"
        a1, b1 = src + " ", dst + " "
        a2, b2 = src + ".", dst + "."
        if a1 in s or a2 in s:
            p.write_bytes(s.replace(a1, b1).replace(a2, b2).encode())
            count += 1
    if count:
        print(f"Update {count} files in {src_dir}: {src} --> {dst}")


pypika_dir = Path(pypika.__file__).parent
pypika_tortoise_dir = pypika_dir.with_name("pypika_tortoise")
if not pypika_tortoise_dir.exists():
    shutil.move(pypika_dir, pypika_tortoise_dir)
    print(f"mv {pypika_dir} {pypika_tortoise_dir}")
else:
    shutil.rmtree(pypika_dir)
    print(f"rm {pypika_dir}")
migrate(pypika_tortoise_dir)

tortoise_dir = Path(tortoise.__file__).parent
migrate(tortoise_dir)

pip_install("pypika", "--force-reinstall")
print("Done.")

After the script executed, you can verify pypika/pypika-tortoise/tortoise work together by: python -c 'from pypika.dialects import ClickHouseQuery;import tortoise'

@jorenham
Copy link
Author

Haha that's quite the hack @waketzheng .

Forking might be a bit easier though 🤷

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants