mtsql 1.12.31__py3-none-any.whl → 1.12.33__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
mt/sql/base.py CHANGED
@@ -25,12 +25,17 @@ __all__ = [
25
25
  "list_views",
26
26
  "table_exists",
27
27
  "create_temp_id_table",
28
+ "create_temp_id_tuple_table",
29
+ "create_temp_str_id_table",
28
30
  "temp_table_name",
29
31
  "temp_table_find_new_id",
30
32
  "temp_table_drop",
31
33
  "to_temp_table",
32
34
  "find_common_ids",
35
+ "find_common_id_tuples",
36
+ "find_common_str_ids",
33
37
  "remove_records_by_id",
38
+ "remove_records_by_str_id",
34
39
  ]
35
40
 
36
41
 
@@ -420,6 +425,108 @@ def create_temp_id_table(
420
425
  return table_name
421
426
 
422
427
 
428
+ def create_temp_id_tuple_table(
429
+ la_ids: list,
430
+ n_cols: int,
431
+ conn: sa.engine.Connection,
432
+ int_type: str = "int",
433
+ chunksize: int = 1000000,
434
+ logger: tp.Optional[logg.IndentedLoggerAdapter] = None,
435
+ ) -> str:
436
+ """Creates a temporary table to containing a list of multi-column ids.
437
+
438
+ Parameters
439
+ ----------
440
+ la_ids : list
441
+ list of fixed-sized arrays of ids to be inserted into the table. Each array must have
442
+ length equal to `n_cols`.
443
+ n_cols : int
444
+ number of columns in the id arrays
445
+ conn : sqlalchemy.engine.Connection
446
+ a connection that has been opened
447
+ int_type : str
448
+ an SQL string representing the int type
449
+ chunksize : int
450
+ maximum number of ids to be inserted in each INSERT statement
451
+ logger : mt.logg.IndentedLoggerAdapter, optional
452
+ logger for debugging
453
+
454
+ Returns
455
+ -------
456
+ table_name : str
457
+ name of the temporary table. The table will be deleted at the end of the connection
458
+ """
459
+
460
+ if n_cols <= 1:
461
+ raise ValueError("n_cols must be greater than 1")
462
+
463
+ table_name = f"tab_{uuid.uuid4().hex}"
464
+
465
+ query_str = f"CREATE TEMP TABLE {table_name}("
466
+ query_str += ",".join((f"id{i+1} {int_type}" for i in range(n_cols)))
467
+ query_str += ");"
468
+ exec_sql(sa.text(query_str), conn, logger=logger)
469
+
470
+ while True:
471
+ la_ids2 = la_ids[:chunksize]
472
+ if len(la_ids2) == 0:
473
+ break
474
+ values = ",".join(
475
+ "(" + ",".join((str(id[i]) for i in range(n_cols))) + ")" for id in la_ids2
476
+ )
477
+ query_str = f"INSERT INTO {table_name}("
478
+ query_str += ",".join((f"id{i+1}" for i in range(n_cols)))
479
+ query_str += f") VALUES {values};"
480
+ exec_sql(sa.text(query_str), conn, logger=logger)
481
+
482
+ la_ids = la_ids[chunksize:]
483
+
484
+ return table_name
485
+
486
+
487
+ def create_temp_str_id_table(
488
+ l_ids: list,
489
+ conn: sa.engine.Connection,
490
+ chunksize: int = 1000000,
491
+ logger: tp.Optional[logg.IndentedLoggerAdapter] = None,
492
+ ) -> str:
493
+ """Creates a temporary table to containing a list of string ids.
494
+
495
+ Parameters
496
+ ----------
497
+ l_ids : list
498
+ list of string ids to be inserted into the table
499
+ conn : sqlalchemy.engine.Connection
500
+ a connection that has been opened
501
+ chunksize : int
502
+ maximum number of ids to be inserted in each INSERT statement
503
+ logger : mt.logg.IndentedLoggerAdapter, optional
504
+ logger for debugging
505
+
506
+ Returns
507
+ -------
508
+ table_name : str
509
+ name of the temporary table. The table will be deleted at the end of the connection
510
+ """
511
+
512
+ table_name = f"tab_{uuid.uuid4().hex}"
513
+
514
+ query_str = f"CREATE TEMP TABLE {table_name}(id character varying);"
515
+ exec_sql(sa.text(query_str), conn, logger=logger)
516
+
517
+ while True:
518
+ l_ids2 = l_ids[:chunksize]
519
+ if len(l_ids2) == 0:
520
+ break
521
+
522
+ values = ",".join((f"('{id}')" for id in l_ids2))
523
+ query_str = f"INSERT INTO {table_name}(id) VALUES {values};"
524
+ exec_sql(sa.text(query_str), conn, logger=logger)
525
+ l_ids = l_ids[chunksize:]
526
+
527
+ return table_name
528
+
529
+
423
530
  def temp_table_name(id: int) -> str:
424
531
  """Converts a temp table id into a temp table name."""
425
532
  return f"mttmp_{id}"
@@ -550,6 +657,109 @@ def find_common_ids(
550
657
  return l_commonIds
551
658
 
552
659
 
660
+ def find_common_id_tuples(
661
+ la_ids: tp.List[tp.List[int]],
662
+ id_cols: tp.List[str],
663
+ frame_name: str,
664
+ engine: sa.engine.Engine,
665
+ schema: tp.Optional[str] = None,
666
+ int_type: str = "int",
667
+ logger: tp.Optional[logg.IndentedLoggerAdapter] = None,
668
+ ) -> tp.List[int]:
669
+ """Finds common ids between a list of ids and the ids in a given frame.
670
+
671
+ Parameters
672
+ ----------
673
+ la_ids : list of list of int
674
+ list of id tuples to be checked
675
+ id_cols : list of str
676
+ name of the id columns in the frame
677
+ frame_name : str
678
+ name of the frame to be checked against
679
+ engine : sqlalchemy.engine.Engine
680
+ connection engine to the server
681
+ schema : str, optional
682
+ schema of the frame. If None, the default schema is used.
683
+ id_cols : list of str
684
+ name of the id column in the frame
685
+ int_type : str
686
+ an SQL string representing the int type of the id column
687
+ logger : mt.logg.IndentedLoggerAdapter, optional
688
+ logger for debugging
689
+
690
+ Returns
691
+ -------
692
+ list of int
693
+ list of common ids
694
+ """
695
+
696
+ with conn_ctx(engine) as conn:
697
+ temp_table = create_temp_id_table(l_ids, conn, int_type=int_type, logger=logger)
698
+
699
+ full_frame_name = frame_sql(frame_name, schema=schema)
700
+
701
+ sql = f"""
702
+ SELECT t.id FROM {temp_table} AS t
703
+ INNER JOIN {full_frame_name} AS f
704
+ ON t.id = f.{id_col};
705
+ """
706
+
707
+ df_common = read_sql(sql, conn, index_col=None, logger=logger)
708
+
709
+ l_commonIds = df_common["id"].tolist()
710
+
711
+ return l_commonIds
712
+
713
+
714
+ def find_common_str_ids(
715
+ l_ids: tp.List[str],
716
+ frame_name: str,
717
+ engine: sa.engine.Engine,
718
+ schema: tp.Optional[str] = None,
719
+ id_col: str = "uuid",
720
+ logger: tp.Optional[logg.IndentedLoggerAdapter] = None,
721
+ ) -> tp.List[int]:
722
+ """Finds common string ids between a list of string ids and the string ids in a given frame.
723
+
724
+ Parameters
725
+ ----------
726
+ l_ids : list of strings
727
+ list of string ids to be checked
728
+ frame_name : str
729
+ name of the frame to be checked against
730
+ engine : sqlalchemy.engine.Engine
731
+ connection engine to the server
732
+ schema : str, optional
733
+ schema of the frame. If None, the default schema is used.
734
+ id_col : str
735
+ name of the string id column in the frame
736
+ logger : mt.logg.IndentedLoggerAdapter, optional
737
+ logger for debugging
738
+
739
+ Returns
740
+ -------
741
+ list of strings
742
+ list of common string ids
743
+ """
744
+
745
+ with conn_ctx(engine) as conn:
746
+ temp_table = create_temp_str_id_table(l_ids, conn, logger=logger)
747
+
748
+ full_frame_name = frame_sql(frame_name, schema=schema)
749
+
750
+ sql = f"""
751
+ SELECT t.id FROM {temp_table} AS t
752
+ INNER JOIN {full_frame_name} AS f
753
+ ON t.id = f.{id_col};
754
+ """
755
+
756
+ df_common = read_sql(sql, conn, index_col=None, logger=logger)
757
+
758
+ l_commonIds = df_common["id"].tolist()
759
+
760
+ return l_commonIds
761
+
762
+
553
763
  def remove_records_by_id(
554
764
  l_ids: tp.List[int],
555
765
  frame_name: str,
@@ -591,3 +801,43 @@ def remove_records_by_id(
591
801
  """
592
802
 
593
803
  exec_sql(sql, conn, logger=logger)
804
+
805
+
806
+ def remove_records_by_str_id(
807
+ l_ids: tp.List[str],
808
+ frame_name: str,
809
+ engine: sa.engine.Engine,
810
+ schema: tp.Optional[str] = None,
811
+ id_col: str = "id",
812
+ logger: tp.Optional[logg.IndentedLoggerAdapter] = None,
813
+ ):
814
+ """Removes records from a frame by a list of string ids.
815
+
816
+ Parameters
817
+ ----------
818
+ l_ids : list of strings
819
+ list of string ids to be removed
820
+ frame_name : str
821
+ name of the frame to be modified
822
+ engine : sqlalchemy.engine.Engine
823
+ connection engine to the server
824
+ schema : str, optional
825
+ schema of the frame. If None, the default schema is used.
826
+ id_col : str
827
+ name of the id column in the frame
828
+ logger : mt.logg.IndentedLoggerAdapter, optional
829
+ logger for debugging
830
+ """
831
+
832
+ with conn_ctx(engine) as conn:
833
+ temp_table = create_temp_str_id_table(l_ids, conn, logger=logger)
834
+
835
+ full_frame_name = frame_sql(frame_name, schema=schema)
836
+
837
+ sql = f"""
838
+ DELETE FROM {full_frame_name}
839
+ USING {temp_table} AS t
840
+ WHERE {full_frame_name}.{id_col} = t.id;
841
+ """
842
+
843
+ exec_sql(sql, conn, logger=logger)
mt/sql/version.py CHANGED
@@ -1,5 +1,5 @@
1
1
  MAJOR_VERSION = 1
2
2
  MINOR_VERSION = 12
3
- PATCH_VERSION = 31
3
+ PATCH_VERSION = 33
4
4
  version = '{}.{}.{}'.format(MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION)
5
5
  __all__ = ['MAJOR_VERSION', 'MINOR_VERSION', 'PATCH_VERSION', 'version']
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mtsql
3
- Version: 1.12.31
3
+ Version: 1.12.33
4
4
  Summary: Extra Python modules to deal with the interaction between pandas dataframes and remote SQL servers, for Minh-Tri Pham
5
5
  Home-page: https://github.com/inteplus/mtsql
6
6
  Author: Minh-Tri Pham
@@ -12,8 +12,8 @@ Requires-Dist: tzlocal
12
12
  Requires-Dist: tqdm
13
13
  Requires-Dist: psycopg[binary]
14
14
  Requires-Dist: redshift_connector>=2.1.5
15
- Requires-Dist: mtbase>=4.3.2
16
- Requires-Dist: mtpandas>=1.17.16
15
+ Requires-Dist: mtbase>=4.33.15
16
+ Requires-Dist: mtpandas>=1.17.20
17
17
  Dynamic: author
18
18
  Dynamic: home-page
19
19
  Dynamic: license-file
@@ -1,17 +1,17 @@
1
1
  mt/sql/__init__.py,sha256=b7zO50apZxt9Hg2eOkJhRLrXgACR8eS5b-Rphdn5qNQ,44
2
- mt/sql/base.py,sha256=CLFKd-rJtIUGLm37WtxeFLzhX48LgGpEoz6noR4qfXo,16510
2
+ mt/sql/base.py,sha256=HJzMlKO-SX3aLTMnOrvhrInfNi9O7WMD3tuV2yZIdJg,23863
3
3
  mt/sql/mysql.py,sha256=n2ENDctdUqZuSaDAcrqZYtPtawq3Wx4dOPCRsCB5Q4w,4894
4
4
  mt/sql/psql.py,sha256=U8XEyg4rQYr5gm8KohRWrpCNJKl5WC1yxJMBkkm1k_A,68125
5
5
  mt/sql/sqlite.py,sha256=T2ak_hhNi_zRfpg_gp8JhNHn7D2kl4i-Ey6-9ANMtz0,8678
6
- mt/sql/version.py,sha256=e7OodvUPDd0qLszM8zWrGxkmyhHFVodAR8B3CnSzs7g,208
6
+ mt/sql/version.py,sha256=3roEiAIfAeKb5dA-3ZmquKI_ZMs8TFD5x-PCcvQBLe4,208
7
7
  mt/sql/redshift/__init__.py,sha256=S-eRxJWcrvncF7LZXuulCdPV-UERu9eiw6uyDb5aGsM,443
8
8
  mt/sql/redshift/commands.py,sha256=xhGUBf3bL66EYdZI5HCUtOx-XqPCnXT_P-LnhPgtzrY,40193
9
9
  mt/sql/redshift/ddl.py,sha256=eUcZj9oIajiE1wKKBAP-V64gYJ7cVnSAt8dLFfluOJA,9777
10
10
  mt/sql/redshift/dialect.py,sha256=-0JjJubZZHRw0abhl6H6rKWaUE9pKtGwAuX-62T0e_c,53399
11
11
  mt/sql/redshift/main.py,sha256=H8_5sjtJ7dzWoCMXzPNjYhrMQ18eLUQ9xg-aYl5QeTc,17104
12
12
  mt/sql/redshift/redshift-ca-bundle.crt,sha256=532qYkOpQOstFE0mdXE1GVtL3v00XDKgZNTr6gK5-KE,8621
13
- mtsql-1.12.31.dist-info/licenses/LICENSE,sha256=PojkRlQzTT5Eg6Nj03XoIVEefN3u8iiIFf1p4rqe_t4,1070
14
- mtsql-1.12.31.dist-info/METADATA,sha256=bJET1fnqtrkAZ1Qz8UzM7c2E0PL1X65I5AN1h6wlY1Q,734
15
- mtsql-1.12.31.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
- mtsql-1.12.31.dist-info/top_level.txt,sha256=WcqGFu9cV7iMZg09iam8eNxUvGpLSKKF2Iubf6SJVOo,3
17
- mtsql-1.12.31.dist-info/RECORD,,
13
+ mtsql-1.12.33.dist-info/licenses/LICENSE,sha256=PojkRlQzTT5Eg6Nj03XoIVEefN3u8iiIFf1p4rqe_t4,1070
14
+ mtsql-1.12.33.dist-info/METADATA,sha256=MEQHkGnmBIr4lwNZrMKlCCbUNUOmprFJXE3a0xt5Slg,736
15
+ mtsql-1.12.33.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
16
+ mtsql-1.12.33.dist-info/top_level.txt,sha256=WcqGFu9cV7iMZg09iam8eNxUvGpLSKKF2Iubf6SJVOo,3
17
+ mtsql-1.12.33.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5