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

agronholm / sqlacodegen / 7052416992

30 Nov 2023 09:20PM UTC coverage: 99.035% (+1.4%) from 97.636%
7052416992

push

github

agronholm
Updated GitHub actions

1129 of 1140 relevant lines covered (99.04%)

7.96 hits per line

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

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

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

9
import pytest
10✔
10

11
from sqlacodegen.generators import _sqla_version
10✔
12

13
from .conftest import requires_sqlalchemy_1_4
10✔
14

15
future_imports = "from __future__ import annotations\n\n"
10✔
16

17
if _sqla_version < (1, 4):
10✔
18
    declarative_package = "sqlalchemy.ext.declarative"
×
19
else:
×
20
    declarative_package = "sqlalchemy.orm"
10✔
21

22

23
@pytest.fixture
10✔
24
def db_path(tmp_path: Path) -> Path:
10✔
25
    path = tmp_path / "test.db"
10✔
26
    with sqlite3.connect(str(path)) as conn:
10✔
27
        cursor = conn.cursor()
10✔
28
        cursor.execute(
10✔
29
            "CREATE TABLE foo (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL)"
10✔
30
        )
31

32
    return path
10✔
33

34

35
def test_cli_tables(db_path: Path, tmp_path: Path) -> None:
10✔
36
    output_path = tmp_path / "outfile"
10✔
37
    subprocess.run(
10✔
38
        [
10✔
39
            "sqlacodegen",
10✔
40
            f"sqlite:///{db_path}",
10✔
41
            "--generator",
10✔
42
            "tables",
10✔
43
            "--outfile",
10✔
44
            str(output_path),
10✔
45
        ],
46
        check=True,
10✔
47
    )
48

49
    assert (
10✔
50
        output_path.read_text()
51
        == """\
52
from sqlalchemy import Column, Integer, MetaData, Table, Text
53

54
metadata = MetaData()
55

56

57
t_foo = Table(
58
    'foo', metadata,
59
    Column('id', Integer, primary_key=True),
60
    Column('name', Text, nullable=False)
61
)
62
"""
63
    )
6✔
64

65

66
def test_cli_declarative(db_path: Path, tmp_path: Path) -> None:
10✔
67
    output_path = tmp_path / "outfile"
10✔
68
    subprocess.run(
10✔
69
        [
10✔
70
            "sqlacodegen",
10✔
71
            f"sqlite:///{db_path}",
10✔
72
            "--generator",
10✔
73
            "declarative",
10✔
74
            "--outfile",
10✔
75
            str(output_path),
10✔
76
        ],
77
        check=True,
10✔
78
    )
79

80
    if _sqla_version < (2, 0):
10✔
81
        assert (
5✔
82
            output_path.read_text()
83
            == f"""\
84
from sqlalchemy import Column, Integer, Text
85
from {declarative_package} import declarative_base
86

87
Base = declarative_base()
88

89

90
class Foo(Base):
91
    __tablename__ = 'foo'
92

93
    id = Column(Integer, primary_key=True)
94
    name = Column(Text, nullable=False)
95
"""
96
        )
3✔
97
    else:
98
        assert (
5✔
99
            output_path.read_text()
100
            == """\
101
from sqlalchemy import Integer, Text
102
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
103

104
class Base(DeclarativeBase):
105
    pass
106

107

108
class Foo(Base):
109
    __tablename__ = 'foo'
110

111
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
112
    name: Mapped[str] = mapped_column(Text)
113
"""
114
        )
3✔
115

116

117
def test_cli_dataclass(db_path: Path, tmp_path: Path) -> None:
10✔
118
    output_path = tmp_path / "outfile"
10✔
119
    subprocess.run(
10✔
120
        [
10✔
121
            "sqlacodegen",
10✔
122
            f"sqlite:///{db_path}",
10✔
123
            "--generator",
10✔
124
            "dataclasses",
10✔
125
            "--outfile",
10✔
126
            str(output_path),
10✔
127
        ],
128
        check=True,
10✔
129
    )
130

131
    if _sqla_version < (2, 0):
10✔
132
        assert (
5✔
133
            output_path.read_text()
134
            == f"""\
135
{future_imports}from dataclasses import dataclass, field
136

137
from sqlalchemy import Column, Integer, Text
138
from sqlalchemy.orm import registry
139

140
mapper_registry = registry()
141

142

143
@mapper_registry.mapped
144
@dataclass
145
class Foo:
146
    __tablename__ = 'foo'
147
    __sa_dataclass_metadata_key__ = 'sa'
148

149
    id: int = field(init=False, metadata={{'sa': Column(Integer, primary_key=True)}})
150
    name: str = field(metadata={{'sa': Column(Text, nullable=False)}})
151
"""
152
        )
3✔
153
    else:
154
        assert (
5✔
155
            output_path.read_text()
156
            == """\
157
from sqlalchemy import Integer, Text
158
from sqlalchemy.orm import DeclarativeBase, Mapped, MappedAsDataclass, mapped_column
159

160
class Base(MappedAsDataclass, DeclarativeBase):
161
    pass
162

163

164
class Foo(Base):
165
    __tablename__ = 'foo'
166

167
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
168
    name: Mapped[str] = mapped_column(Text)
169
"""
170
        )
3✔
171

172

173
@requires_sqlalchemy_1_4
10✔
174
def test_cli_sqlmodels(db_path: Path, tmp_path: Path) -> None:
10✔
175
    output_path = tmp_path / "outfile"
5✔
176
    subprocess.run(
5✔
177
        [
5✔
178
            "sqlacodegen",
5✔
179
            f"sqlite:///{db_path}",
5✔
180
            "--generator",
5✔
181
            "sqlmodels",
5✔
182
            "--outfile",
5✔
183
            str(output_path),
5✔
184
        ],
185
        check=True,
5✔
186
    )
187

188
    assert (
5✔
189
        output_path.read_text()
190
        == """\
191
from typing import Optional
192

193
from sqlalchemy import Column, Integer, Text
194
from sqlmodel import Field, SQLModel
195

196
class Foo(SQLModel, table=True):
197
    id: Optional[int] = Field(default=None, sa_column=Column('id', Integer, \
198
primary_key=True))
199
    name: str = Field(sa_column=Column('name', Text, nullable=False))
200
"""
201
    )
3✔
202

203

204
def test_main() -> None:
10✔
205
    expected_version = version("sqlacodegen")
10✔
206
    completed = subprocess.run(
10✔
207
        [sys.executable, "-m", "sqlacodegen", "--version"],
10✔
208
        stdout=subprocess.PIPE,
10✔
209
        check=True,
10✔
210
    )
211
    assert completed.stdout.decode().strip() == expected_version
10✔
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

© 2025 Coveralls, Inc