Skip to content

Commit aa0a092

Browse files
techousemackuba
andauthored
✨ MySQL Unix socket connection support (#137)
MySQL Unix socket connection support --------- Co-authored-by: Kuba Suder <jakub.suder@gmail.com>
1 parent 9d7031d commit aa0a092

File tree

6 files changed

+31
-1
lines changed

6 files changed

+31
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Options:
4949
--mysql-password TEXT MySQL password
5050
-h, --mysql-host TEXT MySQL host. Defaults to localhost.
5151
-P, --mysql-port INTEGER MySQL port. Defaults to 3306.
52+
-k, --mysql-socket PATH Path to MySQL unix socket file.
5253
-S, --skip-ssl Disable MySQL connection encryption.
5354
-i, --mysql-insert-method [DEFAULT|IGNORE|UPDATE]
5455
MySQL insert method. DEFAULT will throw

docs/README.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Connection Options
2929
- ``-h, --mysql-host TEXT``: MySQL host. Defaults to localhost.
3030
- ``-P, --mysql-port INTEGER``: MySQL port. Defaults to 3306.
3131
- ``-S, --skip-ssl``: Disable MySQL connection encryption.
32+
- ``--mysql-socket TEXT``: Path to MySQL unix socket file.
3233

3334
Transfer Options
3435
""""""""""""""""

src/sqlite3_to_mysql/cli.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@
6262
@click.option("--mysql-password", default=None, help="MySQL password")
6363
@click.option("-h", "--mysql-host", default="localhost", help="MySQL host. Defaults to localhost.")
6464
@click.option("-P", "--mysql-port", type=int, default=3306, help="MySQL port. Defaults to 3306.")
65+
@click.option(
66+
"-k",
67+
"--mysql-socket",
68+
type=click.Path(exists=True),
69+
default=None,
70+
help="Path to MySQL unix socket file.",
71+
)
6572
@click.option("-S", "--skip-ssl", is_flag=True, help="Disable MySQL connection encryption.")
6673
@click.option(
6774
"-i",
@@ -137,6 +144,7 @@ def cli(
137144
mysql_database: str,
138145
mysql_host: str,
139146
mysql_port: int,
147+
mysql_socket: t.Optional[str],
140148
skip_ssl: bool,
141149
mysql_insert_method: str,
142150
mysql_truncate_tables: bool,
@@ -157,6 +165,9 @@ def cli(
157165
"""Transfer SQLite to MySQL using the provided CLI options."""
158166
click.echo(_copyright_header)
159167
try:
168+
if mysql_port and mysql_socket:
169+
raise click.ClickException("Error: Can only specify either -P/--mysql-port or -k/--mysql-socket, not both.")
170+
160171
if mysql_collation:
161172
charset_collations: t.Tuple[str, ...] = tuple(
162173
cs.collation for cs in mysql_supported_character_sets(mysql_charset.lower())
@@ -183,6 +194,7 @@ def cli(
183194
mysql_database=mysql_database,
184195
mysql_host=mysql_host,
185196
mysql_port=mysql_port,
197+
mysql_socket=mysql_socket,
186198
mysql_ssl_disabled=skip_ssl,
187199
mysql_insert_method=mysql_insert_method,
188200
mysql_truncate_tables=mysql_truncate_tables,

src/sqlite3_to_mysql/transporter.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,15 @@ def __init__(self, **kwargs: tx.Unpack[SQLite3toMySQLParams]):
7575

7676
self._mysql_port = kwargs.get("mysql_port", 3306) or 3306
7777

78+
if kwargs.get("mysql_socket") is not None:
79+
if not os.path.exists(str(kwargs.get("mysql_socket"))):
80+
raise FileNotFoundError("MySQL socket does not exist")
81+
else:
82+
self._mysql_socket = realpath(str(kwargs.get("mysql_socket")))
83+
self._mysql_port = None
84+
else:
85+
self._mysql_socket = None
86+
7887
self._sqlite_tables = kwargs.get("sqlite_tables") or tuple()
7988

8089
self._without_foreign_keys = bool(self._sqlite_tables) or bool(kwargs.get("without_foreign_keys", False))
@@ -144,6 +153,7 @@ def __init__(self, **kwargs: tx.Unpack[SQLite3toMySQLParams]):
144153
password=self._mysql_password,
145154
host=self._mysql_host,
146155
port=self._mysql_port,
156+
unix_socket=self._mysql_socket,
147157
ssl_disabled=self._mysql_ssl_disabled,
148158
use_pure=True,
149159
charset=self._mysql_charset,

src/sqlite3_to_mysql/types.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class SQLite3toMySQLParams(tx.TypedDict):
2020
mysql_password: t.Optional[t.Union[str, bool]]
2121
mysql_host: t.Optional[str]
2222
mysql_port: t.Optional[int]
23+
mysql_socket: t.Optional[t.Union[str, "os.PathLike[t.Any]"]]
2324
mysql_ssl_disabled: t.Optional[bool]
2425
chunk: t.Optional[int]
2526
quiet: t.Optional[bool]
@@ -48,7 +49,8 @@ class SQLite3toMySQLAttributes:
4849
_mysql_user: str
4950
_mysql_password: t.Optional[str]
5051
_mysql_host: str
51-
_mysql_port: int
52+
_mysql_port: t.Optional[int]
53+
_mysql_socket: t.Optional[t.Union[str, "os.PathLike[t.Any]"]]
5254
_mysql_ssl_disabled: bool
5355
_chunk_size: t.Optional[int]
5456
_quiet: bool

tests/unit/types_test.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def test_sqlite3_to_mysql_params_typing(self) -> None:
2323
"mysql_password": "password",
2424
"mysql_host": "localhost",
2525
"mysql_port": 3306,
26+
"mysql_socket": "/var/run/mysqld/mysqld.sock",
2627
"mysql_ssl_disabled": True,
2728
"chunk": 1000,
2829
"quiet": False,
@@ -50,6 +51,7 @@ def test_sqlite3_to_mysql_params_typing(self) -> None:
5051
assert params["mysql_password"] == "password"
5152
assert params["mysql_host"] == "localhost"
5253
assert params["mysql_port"] == 3306
54+
assert params["mysql_socket"] == "/var/run/mysqld/mysqld.sock"
5355
assert params["mysql_ssl_disabled"] is True
5456
assert params["chunk"] == 1000
5557
assert params["quiet"] is False
@@ -90,6 +92,7 @@ def __init__(self) -> None:
9092
self._mysql_password = "password"
9193
self._mysql_host = "localhost"
9294
self._mysql_port = 3306
95+
self._mysql_socket = "/var/run/mysqld/mysqld.sock"
9396
self._mysql_ssl_disabled = True
9497
self._chunk_size = 1000
9598
self._quiet = False
@@ -129,6 +132,7 @@ def __init__(self) -> None:
129132
assert instance._mysql_password == "password"
130133
assert instance._mysql_host == "localhost"
131134
assert instance._mysql_port == 3306
135+
assert instance._mysql_socket == "/var/run/mysqld/mysqld.sock"
132136
assert instance._mysql_ssl_disabled is True
133137
assert instance._chunk_size == 1000
134138
assert instance._quiet is False

0 commit comments

Comments
 (0)