tai-sql 0.7.0__tar.gz → 0.7.2__tar.gz

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.
Files changed (225) hide show
  1. {tai_sql-0.7.0 → tai_sql-0.7.2}/PKG-INFO +1 -1
  2. {tai_sql-0.7.0 → tai_sql-0.7.2}/pyproject.toml +1 -1
  3. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_schema/schemas/chatbot.py +55 -2
  4. tai_sql-0.7.2/tai_sql/generators/__init__.py +13 -0
  5. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/context.py +7 -3
  6. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/shared/utils/rls.py.jinja2 +83 -12
  7. tai_sql-0.7.0/tai_sql/generators/__init__.py +0 -6
  8. {tai_sql-0.7.0 → tai_sql-0.7.2}/LICENSE +0 -0
  9. {tai_sql-0.7.0 → tai_sql-0.7.2}/README.md +0 -0
  10. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/__init__.py +0 -0
  11. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/__init__.py +0 -0
  12. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_backup/__init__.py +0 -0
  13. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_backup/main.py +0 -0
  14. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_deploy/__init__.py +0 -0
  15. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_deploy/config.py +0 -0
  16. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_deploy/local.py +0 -0
  17. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_deploy/main.py +0 -0
  18. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_deploy/workflow.py +0 -0
  19. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_feed/__init__.py +0 -0
  20. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_feed/main.py +0 -0
  21. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_generate/__init__.py +0 -0
  22. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_generate/funcs.py +0 -0
  23. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_generate/main.py +0 -0
  24. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_info/__init__.py +0 -0
  25. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_info/main.py +0 -0
  26. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_info/status.py +0 -0
  27. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_init/__init__.py +0 -0
  28. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_init/main.py +0 -0
  29. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_init/model.py +0 -0
  30. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_install/__init__.py +0 -0
  31. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_install/main.py +0 -0
  32. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_ping/__init__.py +0 -0
  33. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_ping/main.py +0 -0
  34. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_pull/__init__.py +0 -0
  35. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_pull/funcs.py +0 -0
  36. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_pull/main.py +0 -0
  37. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_restore/__init__.py +0 -0
  38. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_restore/main.py +0 -0
  39. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_rules/__init__.py +0 -0
  40. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_rules/main.py +0 -0
  41. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_schema/__init__.py +0 -0
  42. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_schema/model.py +0 -0
  43. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_schema/new.py +0 -0
  44. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_schema/schemas/__init__.py +0 -0
  45. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_schema/schemas/auth.py +0 -0
  46. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_schema/schemas/base.py +0 -0
  47. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_schema/schemas/default.py +0 -0
  48. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/cmd_schema/set_default.py +0 -0
  49. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/prompts.py +0 -0
  50. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/utils/__init__.py +0 -0
  51. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/utils/connectivity.py +0 -0
  52. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/utils/create.py +0 -0
  53. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/utils/github/__init__.py +0 -0
  54. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/utils/github/auth.py +0 -0
  55. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/utils/github/client.py +0 -0
  56. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/commands/utils/github/models.py +0 -0
  57. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/errors.py +0 -0
  58. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/main.py +0 -0
  59. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/preamble.py +0 -0
  60. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/services/__init__.py +0 -0
  61. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/cli/services/backup.py +0 -0
  62. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/connection/README.md +0 -0
  63. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/connection/__init__.py +0 -0
  64. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/connection/provider.py +0 -0
  65. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/connection/recipe.py +0 -0
  66. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/connection/session.py +0 -0
  67. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/connection/sources.py +0 -0
  68. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/crypto.py +0 -0
  69. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/drivers/__init__.py +0 -0
  70. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/drivers/base.py +0 -0
  71. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/drivers/bigquery.py +0 -0
  72. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/drivers/capabilities.py +0 -0
  73. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/drivers/mysql.py +0 -0
  74. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/drivers/postgresql.py +0 -0
  75. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/drivers/sqlserver.py +0 -0
  76. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/errors/README.md +0 -0
  77. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/errors/__init__.py +0 -0
  78. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/errors/collector.py +0 -0
  79. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/errors/render.py +0 -0
  80. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/errors/types.py +0 -0
  81. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/feed/README.md +0 -0
  82. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/feed/__init__.py +0 -0
  83. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/feed/collect.py +0 -0
  84. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/feed/executor.py +0 -0
  85. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/feed/feeder.py +0 -0
  86. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/feed/plan.py +0 -0
  87. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/feed/presenter.py +0 -0
  88. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/feed/records.py +0 -0
  89. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/feed/transform.py +0 -0
  90. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/base.py +0 -0
  91. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/diagram/README.md +0 -0
  92. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/diagram/__init__.py +0 -0
  93. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/diagram/assets/README.md +0 -0
  94. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/diagram/assets/cytoscape.min.js +0 -0
  95. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/diagram/builder.py +0 -0
  96. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/diagram/generator.py +0 -0
  97. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/diagram/graphviz_render.py +0 -0
  98. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/diagram/html_render.py +0 -0
  99. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/diagram/layout.py +0 -0
  100. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/diagram/model.py +0 -0
  101. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/diagram/templates/er.html.jinja2 +0 -0
  102. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/diagram/themes.py +0 -0
  103. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/__init__.py +0 -0
  104. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/calculated.py +0 -0
  105. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/base.py.jinja2 +0 -0
  106. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/domain/__init__.py.jinja2 +0 -0
  107. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/domain/dao.py.jinja2 +0 -0
  108. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/domain/dtos.py.jinja2 +0 -0
  109. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/domain/model.py.jinja2 +0 -0
  110. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/facade.py.jinja2 +0 -0
  111. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/macros/aggregation.jinja2 +0 -0
  112. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/macros/dataframe.jinja2 +0 -0
  113. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/macros/filters.jinja2 +0 -0
  114. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/macros/hierarchy.jinja2 +0 -0
  115. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/macros/read.jinja2 +0 -0
  116. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/macros/triggers.jinja2 +0 -0
  117. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/macros/upsert.jinja2 +0 -0
  118. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/macros/vector.jinja2 +0 -0
  119. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/macros/write.jinja2 +0 -0
  120. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/session.py.jinja2 +0 -0
  121. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/shared/__init__.py.jinja2 +0 -0
  122. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/shared/aggregation.py.jinja2 +0 -0
  123. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/shared/context.py.jinja2 +0 -0
  124. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/shared/utils/__init__.py.jinja2 +0 -0
  125. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/shared/utils/encoders.py.jinja2 +0 -0
  126. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/shared/utils/funcs.py.jinja2 +0 -0
  127. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/shared/utils/hierarchy.py.jinja2 +0 -0
  128. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/templates/shared/vector.py.jinja2 +0 -0
  129. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/triggers/__init__.py +0 -0
  130. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/triggers/analyzer.py +0 -0
  131. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/triggers/renderer.py +0 -0
  132. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/triggers/steps.py +0 -0
  133. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/python_client/triggers/transformer.py +0 -0
  134. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/rules/__init__.py +0 -0
  135. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/generators/rules/templates/schema.md.jinja2 +0 -0
  136. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/introspect/README.md +0 -0
  137. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/introspect/__init__.py +0 -0
  138. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/introspect/blueprint.py +0 -0
  139. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/introspect/build.py +0 -0
  140. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/introspect/defaults.py +0 -0
  141. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/introspect/naming.py +0 -0
  142. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/introspect/reader.py +0 -0
  143. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/introspect/templates/schema.py.jinja2 +0 -0
  144. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/introspect/types.py +0 -0
  145. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/introspect/writer.py +0 -0
  146. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/README.md +0 -0
  147. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/__init__.py +0 -0
  148. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/analysis/README.md +0 -0
  149. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/analysis/__init__.py +0 -0
  150. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/analysis/calculated.py +0 -0
  151. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/analysis/collector.py +0 -0
  152. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/analysis/column_analyzer.py +0 -0
  153. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/analysis/constraints.py +0 -0
  154. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/analysis/hints.py +0 -0
  155. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/analysis/relation_analyzer.py +0 -0
  156. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/analysis/schema_analyzer.py +0 -0
  157. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/declarative/README.md +0 -0
  158. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/declarative/__init__.py +0 -0
  159. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/declarative/annotations.py +0 -0
  160. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/declarative/base.py +0 -0
  161. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/declarative/calculated.py +0 -0
  162. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/declarative/columns.py +0 -0
  163. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/declarative/constraints.py +0 -0
  164. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/declarative/datasource.py +0 -0
  165. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/declarative/descriptors.py +0 -0
  166. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/declarative/encoders.py +0 -0
  167. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/declarative/enumerations.py +0 -0
  168. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/declarative/relations.py +0 -0
  169. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/declarative/table.py +0 -0
  170. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/declarative/trigger_api.py +0 -0
  171. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/declarative/triggers.py +0 -0
  172. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/declarative/view.py +0 -0
  173. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/mapping/README.md +0 -0
  174. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/mapping/__init__.py +0 -0
  175. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/mapping/sqlalchemy_mapper.py +0 -0
  176. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/model/README.md +0 -0
  177. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/model/__init__.py +0 -0
  178. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/model/column.py +0 -0
  179. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/model/constraints.py +0 -0
  180. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/model/entity.py +0 -0
  181. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/model/enumeration.py +0 -0
  182. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/model/relation.py +0 -0
  183. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/model/schema.py +0 -0
  184. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/model/trigger.py +0 -0
  185. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/naming.py +0 -0
  186. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/ordering.py +0 -0
  187. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/registry.py +0 -0
  188. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/orm/types.py +0 -0
  189. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/project/README.md +0 -0
  190. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/project/__init__.py +0 -0
  191. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/project/config.py +0 -0
  192. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/project/context.py +0 -0
  193. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/project/manager.py +0 -0
  194. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/project/paths.py +0 -0
  195. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/rules/README.md +0 -0
  196. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/rules/__init__.py +0 -0
  197. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/rules/catalog.py +0 -0
  198. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/rules/installer.py +0 -0
  199. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/rules/meta.py +0 -0
  200. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/rules/service.py +0 -0
  201. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/rules/staleness.py +0 -0
  202. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/rules/static/comandos.md +0 -0
  203. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/rules/static/errores.md +0 -0
  204. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/rules/static/modelo.md +0 -0
  205. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/schema.py +0 -0
  206. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/README.md +0 -0
  207. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/__init__.py +0 -0
  208. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/diff/__init__.py +0 -0
  209. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/diff/constraints.py +0 -0
  210. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/diff/indexes.py +0 -0
  211. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/diff/tables.py +0 -0
  212. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/diff/views.py +0 -0
  213. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/executor.py +0 -0
  214. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/plan/__init__.py +0 -0
  215. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/plan/planner.py +0 -0
  216. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/plan/statements.py +0 -0
  217. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/presenter.py +0 -0
  218. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/report.py +0 -0
  219. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/safety.py +0 -0
  220. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/state/__init__.py +0 -0
  221. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/state/local.py +0 -0
  222. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/state/model.py +0 -0
  223. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/state/normalize.py +0 -0
  224. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/state/remote.py +0 -0
  225. {tai_sql-0.7.0 → tai_sql-0.7.2}/tai_sql/sync/synchronizer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tai-sql
3
- Version: 0.7.0
3
+ Version: 0.7.2
4
4
  Summary: SQL database management and code generation tool
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "tai-sql"
3
- version = "0.7.0"
3
+ version = "0.7.2"
4
4
  description = "SQL database management and code generation tool"
5
5
  license = "MIT"
6
6
  license-files = ["LICENSE"]
@@ -6,7 +6,7 @@ from .base import SchemaTemplate
6
6
 
7
7
 
8
8
  class ChatbotSchema(SchemaTemplate):
9
- """Plantilla chatbot: Usuario, Chat, Mensaje, TokenUsage, ToolCall, vistas"""
9
+ """Plantilla chatbot: Chat, Mensaje, TokenUsage, ToolCall, LimitePresupuesto y vistas"""
10
10
 
11
11
  def get_content(self) -> str:
12
12
  return dedent(f'''
@@ -113,7 +113,11 @@ class ChatbotSchema(SchemaTemplate):
113
113
  total_tokens: col[int] = column(default=0, description='Total de tokens consumidos')
114
114
  model_name: col[str] = column(description='Nombre del modelo utilizado')
115
115
  provider: col[str] = column(description='Proveedor del modelo (OpenAI, Anthropic, etc.)')
116
- cost_usd: col[float | None] = column(description='Costo estimado en USD')
116
+ cost_usd: col[float | None] = column(description='Costo estimado en USD, con el margen ya aplicado')
117
+ # Los precios con los que se calculó: una factura antigua se reconstruye aunque el
118
+ # catálogo de .config.json valga hoy otra cosa
119
+ input_usd_millon: col[float | None] = column(description='USD por millón de tokens de entrada aplicados')
120
+ output_usd_millon: col[float | None] = column(description='USD por millón de tokens de salida aplicados')
117
121
  timestamp: col[datetime] = column(default=datetime.now, description='Timestamp del consumo')
118
122
  message_id: col[bigint] = column(description='ID del mensaje asociado')
119
123
 
@@ -136,6 +140,19 @@ class ChatbotSchema(SchemaTemplate):
136
140
  message: manytoone[Mensaje] = relation(fields=['message_id'], references=['id'], backref='tool_calls') # Relación many-to-one con Mensaje
137
141
 
138
142
 
143
+ class LimitePresupuesto(Table):
144
+ """Tabla que almacena el límite de gasto de cada usuario en cada mes"""
145
+ __tablename__ = "limite_presupuesto"
146
+
147
+ # Una fila por mes: al cerrarse el mes su límite queda congelado y las facturas
148
+ # antiguas no cambian aunque se reparta otra bolsa
149
+ mes: col[str] = column(primary_key=True, description="Mes al que se aplica, como 'YYYY-MM'")
150
+ # La fila con username '*' es la bolsa general, que se reparte entre los usuarios
151
+ username: col[str] = column(primary_key=True, description="Usuario al que aplica, o '*' para la bolsa general")
152
+ limite_eur: col[float] = column(default=10.0, description='Límite de gasto mensual en euros')
153
+ personalizado: col[bool] = column(default=False, description='True si lo fijó el administrador a mano, False si sale del reparto')
154
+
155
+
139
156
  # Definición de vistas
140
157
 
141
158
  class UserStats(View):
@@ -183,6 +200,22 @@ class ChatbotSchema(SchemaTemplate):
183
200
  last_message_timestamp: col[datetime]
184
201
  total_tokens_consumed: col[int]
185
202
  is_active: col[bool]
203
+
204
+
205
+ class ConsumoMensual(View):
206
+ """Vista que muestra el consumo y el coste por usuario, mes y modelo"""
207
+ __tablename__ = "consumo_mensual"
208
+ __query__ = query('consumo_mensual.sql')
209
+
210
+ username: col[str]
211
+ mes: col[datetime]
212
+ provider: col[str]
213
+ model_name: col[str]
214
+ total_prompt_tokens: col[int]
215
+ total_completion_tokens: col[int]
216
+ total_tokens: col[int]
217
+ coste_usd: col[float | None]
218
+ message_count: col[int]
186
219
  ''').strip()
187
220
 
188
221
  def create_views(self, views_dir: Path) -> None:
@@ -260,6 +293,26 @@ class ChatbotSchema(SchemaTemplate):
260
293
  ORDER BY last_message_timestamp DESC NULLS LAST;
261
294
  ''').rstrip()
262
295
 
296
+ consumo_mensual_sql = dedent('''\
297
+ -- Vista para el consumo y el coste por usuario, mes y modelo
298
+ SELECT
299
+ c.username,
300
+ DATE_TRUNC('month', tu.timestamp)::date as mes,
301
+ tu.provider,
302
+ tu.model_name,
303
+ SUM(tu.prompt_tokens) as total_prompt_tokens,
304
+ SUM(tu.completion_tokens) as total_completion_tokens,
305
+ SUM(tu.total_tokens) as total_tokens,
306
+ SUM(tu.cost_usd) as coste_usd,
307
+ COUNT(DISTINCT m.id) as message_count
308
+ FROM chat c
309
+ JOIN mensaje m ON c.id = m.chat_id
310
+ JOIN token_usage tu ON m.id = tu.message_id
311
+ GROUP BY c.username, DATE_TRUNC('month', tu.timestamp), tu.provider, tu.model_name
312
+ ORDER BY mes DESC, c.username, total_tokens DESC;
313
+ ''').rstrip()
314
+
263
315
  (views_dir / 'user_stats.sql').write_text(user_stats_sql, encoding='utf-8')
264
316
  (views_dir / 'token_consumption_stats.sql').write_text(token_consumption_sql, encoding='utf-8')
265
317
  (views_dir / 'chat_activity.sql').write_text(chat_activity_sql, encoding='utf-8')
318
+ (views_dir / 'consumo_mensual.sql').write_text(consumo_mensual_sql, encoding='utf-8')
@@ -0,0 +1,13 @@
1
+ from .base import BaseGenerator
2
+ from .diagram import ERDiagramGenerator
3
+ from .python_client import PythonClientGenerator
4
+ from .python_client import ImportLayout
5
+ from .python_client.context import TemplateContextBuilder
6
+
7
+ __all__ = [
8
+ 'BaseGenerator',
9
+ 'ERDiagramGenerator',
10
+ 'PythonClientGenerator',
11
+ 'ImportLayout',
12
+ 'TemplateContextBuilder',
13
+ ]
@@ -18,9 +18,13 @@ NO le corresponde: analizar el schema (eso es `orm/analysis/`), decidir rutas de
18
18
  salida ni imports (eso es `PythonClientGenerator` con su `ImportLayout`), ni transpilar
19
19
  el AST de un trigger (eso es `triggers/transformer.py`).
20
20
 
21
- Sobre la forma de los dicts: es un contrato con las plantillas, no una API pública.
22
- `tests/golden/*.json` lo congela entero y `tests/test_golden_output.py` compara el
23
- resultado final fichero a fichero, que es la comprobación que de verdad importa.
21
+ Qué es público y qué no: **la clase y sus métodos** (`entities`, `entity`, `table`,
22
+ `view`, `column`, `enum`) se exportan desde `tai_sql.generators` y son contrato — los
23
+ usa tai-api para generar sus endpoints a partir del mismo schema, y romperlos rompe la
24
+ librería de al lado. **La forma exacta de los dicts** no lo es: la congela
25
+ `tests/golden/*.json` y la revisa `tests/test_golden_output.py` fichero a fichero, así
26
+ que evoluciona con las plantillas, y ese diff es donde se ve. Añadir una clave es
27
+ seguro; quitar o renombrar una exige mirar también quién más la consume.
24
28
  """
25
29
  from __future__ import annotations
26
30
  from enum import Enum as PyEnum
@@ -6,7 +6,10 @@
6
6
  import functools
7
7
  from collections import deque
8
8
  from dataclasses import dataclass
9
+ from datetime import date, datetime, time
10
+ from decimal import Decimal, InvalidOperation
9
11
  from enum import Enum
12
+ from uuid import UUID
10
13
  from typing import (
11
14
  Any,
12
15
  List,
@@ -110,15 +113,10 @@ class RLS:
110
113
  else:
111
114
  self.values = [self.values]
112
115
 
113
- # Convertir strings numéricas a enteros silenciosamente
114
- converted_values = []
115
- for value in self.values:
116
- if isinstance(value, str) and value.isdigit():
117
- converted_values.append(int(value))
118
- else:
119
- converted_values.append(value)
120
- self.values = converted_values
121
-
116
+ # NOTA: los valores NO se convierten aquí. La coerción de tipos se hace en
117
+ # RLSPredicateBuilder, donde ya se conoce el tipo real de la columna objetivo.
118
+ # Convertir a ciegas rompía valores como "01" sobre columnas de texto.
119
+
122
120
  def applies_to(self, model_cls: Type[ModelType]) -> bool:
123
121
  """Determina si esta regla se aplica al modelo dado."""
124
122
  path = RelationshipPathFinder.find_path(model_cls, self.target_model)
@@ -262,7 +260,10 @@ class RLSPredicateBuilder:
262
260
  except AttributeError:
263
261
  logger.error(f"[{{ schema_name }}] Column {target_column} not found in {target_model.__name__}")
264
262
  return None
265
-
263
+
264
+ # Adaptar los valores al tipo real de la columna
265
+ values = RLSPredicateBuilder._coerce_values(target_col, values)
266
+
266
267
  # Construir predicado base según el operador
267
268
  base_predicate = RLSPredicateBuilder._build_base_predicate(
268
269
  target_col, values, operator
@@ -279,10 +280,80 @@ class RLSPredicateBuilder:
279
280
  source_model, path.path, base_predicate
280
281
  )
281
282
 
283
+ @staticmethod
284
+ def _column_python_type(column: ColumnElement) -> Optional[type]:
285
+ """Obtiene el tipo Python de la columna, o None si no se puede determinar."""
286
+ try:
287
+ return column.type.python_type
288
+ except (AttributeError, NotImplementedError):
289
+ return None
290
+
291
+ @staticmethod
292
+ def _coerce_values(column: ColumnElement, values: List[Any]) -> List[Any]:
293
+ """
294
+ Adapta los valores al tipo Python de la columna objetivo.
295
+
296
+ Los valores suelen llegar como strings (atributos del token), así que una
297
+ columna Integer necesita "1" → 1. Lo que no debe ocurrir es la conversión a la
298
+ inversa: sobre una columna de texto, "01" tiene que seguir siendo "01".
299
+ """
300
+ python_type = RLSPredicateBuilder._column_python_type(column)
301
+ if python_type is None:
302
+ return values
303
+
304
+ coerced = [RLSPredicateBuilder._coerce_value(value, python_type) for value in values]
305
+ if coerced != values:
306
+ logger.debug(f"[{{ schema_name }}] RLS values coerced to {python_type.__name__}: {values} → {coerced}")
307
+ return coerced
308
+
309
+ @staticmethod
310
+ def _coerce_value(value: Any, python_type: type) -> Any:
311
+ """Convierte un valor al tipo Python indicado; lo deja intacto si no es posible."""
312
+ if value is None:
313
+ return value
314
+
315
+ try:
316
+ if python_type is bool:
317
+ if isinstance(value, bool):
318
+ return value
319
+ if isinstance(value, str):
320
+ normalized = value.strip().lower()
321
+ if normalized in ("true", "t", "yes", "y", "1"):
322
+ return True
323
+ if normalized in ("false", "f", "no", "n", "0"):
324
+ return False
325
+ return value
326
+ return bool(value) if isinstance(value, int) else value
327
+
328
+ # Ya es del tipo esperado: no tocar (p.ej. "01" sobre una columna de texto)
329
+ if isinstance(value, python_type):
330
+ return value
331
+
332
+ if python_type is str:
333
+ return str(value)
334
+ if python_type is int:
335
+ return int(str(value).strip())
336
+ if python_type is float:
337
+ return float(str(value).strip())
338
+ if python_type is Decimal:
339
+ return Decimal(str(value).strip())
340
+ if python_type is UUID:
341
+ return UUID(str(value).strip())
342
+ if python_type is datetime:
343
+ return datetime.fromisoformat(str(value).strip())
344
+ if python_type is date:
345
+ return date.fromisoformat(str(value).strip())
346
+ if python_type is time:
347
+ return time.fromisoformat(str(value).strip())
348
+ except (TypeError, ValueError, InvalidOperation):
349
+ logger.warning(f"[{{ schema_name }}] Could not coerce RLS value {value!r} to {python_type.__name__}")
350
+
351
+ return value
352
+
282
353
  @staticmethod
283
354
  def _build_base_predicate(
284
- column: ColumnElement,
285
- values: List[Any],
355
+ column: ColumnElement,
356
+ values: List[Any],
286
357
  operator: RLSOperator
287
358
  ) -> Optional[ColumnElement]:
288
359
  """Construye el predicado base según el operador."""
@@ -1,6 +0,0 @@
1
- from .base import BaseGenerator
2
- from .diagram import ERDiagramGenerator
3
- from .python_client import PythonClientGenerator
4
- from .python_client import ImportLayout
5
-
6
- __all__ = ['BaseGenerator','ERDiagramGenerator', 'PythonClientGenerator', 'ImportLayout']
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes