• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

agronholm / sqlacodegen / 16617628878

30 Jul 2025 08:36AM UTC coverage: 97.595% (+0.2%) from 97.379%
16617628878

Pull #411

github

web-flow
Merge 2c0ee9067 into 240e5b712
Pull Request #411: Fixed same-name imports from wrong package

32 of 32 new or added lines in 3 files covered. (100.0%)

2 existing lines in 2 files now uncovered.

1420 of 1455 relevant lines covered (97.59%)

1.95 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.83
/tests/test_cli.py
1
from __future__ import annotations
2✔
2

3
import sqlite3
2✔
4
import subprocess
2✔
5
import sys
2✔
6
from importlib.metadata import version
2✔
7
from pathlib import Path
2✔
8

9
import pytest
2✔
10

11
future_imports = "from __future__ import annotations\n\n"
2✔
12

13

14
@pytest.fixture
2✔
15
def db_path(tmp_path: Path) -> Path:
2✔
16
    path = tmp_path / "test.db"
2✔
17
    with sqlite3.connect(str(path)) as conn:
2✔
18
        cursor = conn.cursor()
2✔
19
        cursor.execute(
2✔
20
            "CREATE TABLE foo (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL)"
21
        )
22

23
    return path
2✔
24

25

26
def test_cli_tables(db_path: Path, tmp_path: Path) -> None:
2✔
27
    output_path = tmp_path / "outfile"
2✔
28
    subprocess.run(
2✔
29
        [
30
            "sqlacodegen",
31
            f"sqlite:///{db_path}",
32
            "--generator",
33
            "tables",
34
            "--outfile",
35
            str(output_path),
36
        ],
37
        check=True,
38
    )
39

40
    assert (
2✔
41
        output_path.read_text()
42
        == """\
43
from sqlalchemy import Column, Integer, MetaData, Table, Text
44

45
metadata = MetaData()
46

47

48
t_foo = Table(
49
    'foo', metadata,
50
    Column('id', Integer, primary_key=True),
51
    Column('name', Text, nullable=False)
52
)
53
"""
54
    )
55

56

57
def test_cli_declarative(db_path: Path, tmp_path: Path) -> None:
2✔
58
    output_path = tmp_path / "outfile"
2✔
59
    subprocess.run(
2✔
60
        [
61
            "sqlacodegen",
62
            f"sqlite:///{db_path}",
63
            "--generator",
64
            "declarative",
65
            "--outfile",
66
            str(output_path),
67
        ],
68
        check=True,
69
    )
70

71
    assert (
2✔
72
        output_path.read_text()
73
        == """\
74
from sqlalchemy import Integer, Text
75
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
76

77
class Base(DeclarativeBase):
78
    pass
79

80

81
class Foo(Base):
82
    __tablename__ = 'foo'
83

84
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
85
    name: Mapped[str] = mapped_column(Text)
86
"""
87
    )
88

89

90
def test_cli_dataclass(db_path: Path, tmp_path: Path) -> None:
2✔
91
    output_path = tmp_path / "outfile"
2✔
92
    subprocess.run(
2✔
93
        [
94
            "sqlacodegen",
95
            f"sqlite:///{db_path}",
96
            "--generator",
97
            "dataclasses",
98
            "--outfile",
99
            str(output_path),
100
        ],
101
        check=True,
102
    )
103

104
    assert (
2✔
105
        output_path.read_text()
106
        == """\
107
from sqlalchemy import Integer, Text
108
from sqlalchemy.orm import DeclarativeBase, Mapped, MappedAsDataclass, mapped_column
109

110
class Base(MappedAsDataclass, DeclarativeBase):
111
    pass
112

113

114
class Foo(Base):
115
    __tablename__ = 'foo'
116

117
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
118
    name: Mapped[str] = mapped_column(Text)
119
"""
120
    )
121

122

123
def test_cli_sqlmodels(db_path: Path, tmp_path: Path) -> None:
2✔
124
    output_path = tmp_path / "outfile"
2✔
125
    subprocess.run(
2✔
126
        [
127
            "sqlacodegen",
128
            f"sqlite:///{db_path}",
129
            "--generator",
130
            "sqlmodels",
131
            "--outfile",
132
            str(output_path),
133
        ],
134
        check=True,
135
    )
136

137
    assert (
2✔
138
        output_path.read_text()
139
        == """\
140
from sqlalchemy import Column, Integer, Text
141
from sqlmodel import Field, SQLModel
142

143
class Foo(SQLModel, table=True):
144
    id: int = Field(sa_column=Column('id', Integer, primary_key=True))
145
    name: str = Field(sa_column=Column('name', Text))
146
"""
147
    )
148

149

150
def test_cli_engine_arg(db_path: Path, tmp_path: Path) -> None:
2✔
151
    output_path = tmp_path / "outfile"
2✔
152
    subprocess.run(
2✔
153
        [
154
            "sqlacodegen",
155
            f"sqlite:///{db_path}",
156
            "--generator",
157
            "tables",
158
            "--engine-arg",
159
            'connect_args={"timeout": 10}',
160
            "--outfile",
161
            str(output_path),
162
        ],
163
        check=True,
164
    )
165

166
    assert (
2✔
167
        output_path.read_text()
168
        == """\
169
from sqlalchemy import Column, Integer, MetaData, Table, Text
170

171
metadata = MetaData()
172

173

174
t_foo = Table(
175
    'foo', metadata,
176
    Column('id', Integer, primary_key=True),
177
    Column('name', Text, nullable=False)
178
)
179
"""
180
    )
181

182

183
def test_cli_invalid_engine_arg(db_path: Path, tmp_path: Path) -> None:
2✔
184
    output_path = tmp_path / "outfile"
2✔
185

186
    # Expect exception:
187
    # TypeError: 'this_arg_does_not_exist' is an invalid keyword argument for Connection()
188
    with pytest.raises(subprocess.CalledProcessError) as exc_info:
2✔
189
        subprocess.run(
2✔
190
            [
191
                "sqlacodegen",
192
                f"sqlite:///{db_path}",
193
                "--generator",
194
                "tables",
195
                "--engine-arg",
196
                'connect_args={"this_arg_does_not_exist": 10}',
197
                "--outfile",
198
                str(output_path),
199
            ],
200
            check=True,
201
            capture_output=True,
202
        )
203

204
    if sys.version_info < (3, 13):
2✔
205
        assert (
2✔
206
            "'this_arg_does_not_exist' is an invalid keyword argument"
207
            in exc_info.value.stderr.decode()
208
        )
209
    else:
UNCOV
210
        assert (
×
211
            "got an unexpected keyword argument 'this_arg_does_not_exist'"
212
            in exc_info.value.stderr.decode()
213
        )
214

215

216
def test_main() -> None:
2✔
217
    expected_version = version("sqlacodegen")
2✔
218
    completed = subprocess.run(
2✔
219
        [sys.executable, "-m", "sqlacodegen", "--version"],
220
        stdout=subprocess.PIPE,
221
        check=True,
222
    )
223
    assert completed.stdout.decode().strip() == expected_version
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc