agronholm / sqlacodegen

Automatic model code generator for SQLAlchemy
Other
1.87k stars 240 forks source link

sqlacodegen failing with Error: import name 'ArgSpec' from 'inspect' #239

Open raikar321 opened 1 year ago

raikar321 commented 1 year ago

the sqlacodengen library is failing on first install not even showing help

Apparently the ArgSpec has been removed after a long deprecation period in https://github.com/python/cpython/pull/28618, replaced by FullArgSpec. which is causing it to break need help.

Also, confirmed with SQLAlchemy team - https://groups.google.com/g/sqlalchemy/c/OGrv9S8fPLw

I even tried downgrading the SQLAlchemy to version 1.3.24 as mentioned in the readme of sqlacodegen => 0.8.x - 1.3.x still no luck!!!

Error -

PS C:\Users\User\Github\PythonPOC> sqlacodegen --help
Traceback (most recent call last): File "", line 198, in _run_module_as_main File "", line 88, in _runcode File "C:\Users\User\AppData\Roaming\Python\Python311\Scripts\sqlacodegen.exe\ main.py", line 4, in File "C:\Users\User\AppData\Roaming\Python\Python311\site-packages\sqlacodegen n\main.py", line 11, in from sqlacodegen.codegen import CodeGenerator File "C:\Users\User\AppData\Roaming\Python\Python311\site-packages\sqlacodegen n\codegen.py", line 9, in from inspect import ArgSpec ImportError: cannot import name 'ArgSpec' from 'inspect' (C:\Program Files\Pytho on311\Lib\inspect.py)

jpmx commented 1 year ago

As a workaround you can install sqlacodegen to run with Python 3.10.8 using pipx

on MacOS / Linux:

# Install pipx
python -m pip install pipx
python -m pipx ensurepath

# Install pyenv
curl https://pyenv.run | bash
# or brew install pyenv --HEAD
eval "$(pyenv init -)"

# Install your python versions
pyenv install 3.11.0
pyenv install 3.10.8

# Switch to Python 3.10.8
pyenv shell 3.10.8
python --version
# Python 3.10.8

# Install sqlacodegen using Python 3.10.8
python -m pipx install sqlacodegen --python $(which python)
# Inject your SQL driver to sqlacodegen package inside pipx
python -m pipx inject sqlacodegen mysqlclient

# switch back to python 3.11.0
pyenv local 3.11.0
pyenv global 3.11.0
pyenv shell 3.11.0
python --version
# Python 3.11.0

# Verify sqlacodegen runs with 3.10.8
pipx list
   package sqlacodegen 2.3.0, installed using Python 3.10.8
    - sqlacodegen

sqlacodegen --version
# 2.3.0
agronholm commented 1 year ago

Have you tried the 3.0 release candidate?

raikar321 commented 1 year ago

Hey @jpmx and @agronholm, Thanks for the suggestion. I tried both options and it worked. even on 3.10.8 and by upgrading to the beta release 3.0.0rc1 on 3.11 python it worked. But when are the actual live release dates for version 3.0.0 any tentative dates ..?

agronholm commented 1 year ago

I had to shift my focus to other projects while I was working on finishing sqlacodegen 3.0. This is on my TODO list, but behind a couple other projects where I am trying to get new major releases out too. So, I can't give you a timeline.

raikar321 commented 1 year ago

Ok @agronholm thanks for the help :-)

pythoninthegrass commented 1 year ago

Have you tried the 3.0 release candidate?

This solved it for me with Python 3.11.1! Had to run the following with poetry:

λ poetry add git+https://github.com/agronholm/sqlacodegen.git

Updating dependencies
Resolving dependencies... (0.7s)

Writing lock file

Package operations: 2 installs, 0 updates, 0 removals

  • Installing inflect (6.0.2)
  • Installing sqlacodegen (3.0.0rc1.post22 f05d99e)

then was able to use it as expected

λ sqlacodegen --generator dataclasses sqlite:///lunch.db
from __future__ import annotations

from dataclasses import dataclass, field
from datetime import datetime

from sqlalchemy import Column, Integer, String, TIMESTAMP, Table, Text
from sqlalchemy.orm import registry

mapper_registry = registry()
metadata = mapper_registry.metadata

t_lunch_list = Table(
    'lunch_list', metadata,
    Column('restaurants', Text, unique=True),
    Column('option', Text)
)

t_recent_lunch = Table(
    'recent_lunch', metadata,
    Column('restaurants', Text, unique=True),
    Column('date', TIMESTAMP)
)

@mapper_registry.mapped
@dataclass
class Restaurant:
    __tablename__ = 'restaurant'
    __sa_dataclass_metadata_key__ = 'sa'

    id: int = field(init=False, metadata={'sa': Column(Integer, primary_key=True)})
    restaurant: str = field(metadata={'sa': Column(String, nullable=False)})
    option: str = field(metadata={'sa': Column(String, nullable=False)})

My pyproject.toml looks like this

[tool.poetry]
name = "lunch"
version = "0.1.0"
description = ""
authors = ["pythoninthegrass <4097471+pythoninthegrass@users.noreply.github.com>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.11"
PySimpleGUI = "^4.56.0"
passlib = "^1.7.4"
flet = "^0.3.2"
tk = "^0.1.0"
sqlmodel = "^0.0.8"
sqlacodegen = {git = "https://github.com/agronholm/sqlacodegen.git"}

[tool.poetry.dev-dependencies]
icecream = "^2.1.1"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
thinkjrs commented 1 year ago

@agronholm You're amazing and thank you for your work with this.

For those of you using Pipenv simply add the following to your Pipfile:

sqlacodegen = {git = "https://github.com/agronholm/sqlacodegen.git"}

Using requirement.txt:

git+https://github.com/agronholm/sqlacodegen@3.0.0rc1#egg=sqlacodegen

Thanks to @pythoninthegrass for the heads up w/Poetry.

who0joe commented 1 year ago

I had same problem in python 3.11

ImportError: cannot import name 'ArgSpec' from 'inspect' (/usr/local/lib/python3.11/inspect.py)

I tried change 'ArgSpec' to 'FullArgSpec' directly in 'sqlacodegen' package. (at /usr/local/lib/python3.11/site-packages/sqlacodegen/codegen.py) And, It worked fine for me.

Seems it is dangerous to modifying code direct. But, I could helpful if you using this package('sqlacodegen') instantly. (Like, generating only once to make a mapper class for the beginning.)

agronholm commented 1 year ago

You can just install the latest release candidate: pip install --pre sqlacodegen

ManPython commented 1 year ago

https://github.com/agronholm/sqlacodegen/issues/258 This problem still exist for P38

agronholm commented 1 year ago

What's P38?

ManPython commented 1 year ago

Python 38, and confirming P311 this same.. - solved by #comment as sugeestion

musikis commented 1 year ago

you can edit codegen.py at line 9 from inspect import ArgSpec

-> if not hasattr(inspect, 'getfullargspec'):from inspect import ArgSpec

agronholm commented 1 year ago

Best to use the latest pre-release though.

crazydiamondzgy commented 11 months ago

modify the source of sqlacodegen\codegen.py remove line 9 "from inspect import ArgSpec"

in function:

def _getargspec_init(method):
    try:
        if hasattr(inspect, 'getfullargspec'):
            return inspect.getfullargspec(method)
        else:
            return inspect.getargspec(method)
    except TypeError:
        if method is object.__init__:
            return ArgSpec(['self'], None, None, None)
        else:
            return ArgSpec(['self'], 'args', 'kwargs', None)

change to :

def _getargspec_init(method):
    try:
        if hasattr(inspect, 'getfullargspec'):
            return inspect.getfullargspec(method)
        else:
            return inspect.getargspec(method)
    except TypeError:
        if method is object.__init__:
            return inspect.signature(['self'], None, None, None)
        else:
            return inspect.signature(['self'], 'args', 'kwargs', None)
thinkjrs commented 11 months ago

Best to use the latest pre-release though.

modify the source of sqlacodegen\codegen.py remove line 9 "from inspect import ArgSpec"

in function:

def _getargspec_init(method):
    try:
        if hasattr(inspect, 'getfullargspec'):
            return inspect.getfullargspec(method)
        else:
            return inspect.getargspec(method)
    except TypeError:
        if method is object.__init__:
            return ArgSpec(['self'], None, None, None)
        else:
            return ArgSpec(['self'], 'args', 'kwargs', None)

change to :

def _getargspec_init(method):
    try:
        if hasattr(inspect, 'getfullargspec'):
            return inspect.getfullargspec(method)
        else:
            return inspect.getargspec(method)
    except TypeError:
        if method is object.__init__:
            return inspect.signature(['self'], None, None, None)
        else:
            return inspect.signature(['self'], 'args', 'kwargs', None)

As mentioned, it's best to use the pre-release

You can just install the latest release candidate: pip install --pre sqlacodegen

as per https://github.com/agronholm/sqlacodegen/issues/239#issuecomment-1458606942

crazydiamondzgy commented 11 months ago

thanks, pre-release works well

NestorDR commented 9 months ago

Thanks everyone, version 3.0.0 rc3 works well for me too.

duzhuoshanwai commented 3 months ago

https://pypi.org/project/sqlacodegen/ latest version still 2.3.0.post1 need manual to specify version

agronholm commented 3 months ago

https://pypi.org/project/sqlacodegen/ latest version still 2.3.0.post1 need manual to specify version

Or pip install --pre