Create a new table from uploaded file or raw data in the workspace.
()
| 753 | |
| 754 | @tables_bp.route('/create-table', methods=['POST']) |
| 755 | def create_table(): |
| 756 | """Create a new table from uploaded file or raw data in the workspace.""" |
| 757 | try: |
| 758 | has_file = 'file' in request.files |
| 759 | has_raw_data = 'raw_data' in request.files or 'raw_data' in request.form |
| 760 | if not has_file and not has_raw_data: |
| 761 | raise AppError(ErrorCode.INVALID_REQUEST, "No file or raw data provided") |
| 762 | |
| 763 | table_name = request.form.get('table_name') |
| 764 | if not table_name: |
| 765 | raise AppError(ErrorCode.INVALID_REQUEST, "No table name provided") |
| 766 | |
| 767 | workspace = _get_workspace() |
| 768 | sanitized_table_name = parquet_sanitize_table_name(table_name) |
| 769 | replace_source = request.form.get('replace_source', '').lower() == 'true' |
| 770 | |
| 771 | if has_file: |
| 772 | file = request.files['file'] |
| 773 | if not file.filename or not is_supported_file(file.filename): |
| 774 | raise AppError(ErrorCode.INVALID_REQUEST, "Unsupported file format") |
| 775 | try: |
| 776 | safe_name = safe_data_filename(file.filename) |
| 777 | except ValueError: |
| 778 | raise AppError(ErrorCode.INVALID_REQUEST, "Invalid filename") |
| 779 | |
| 780 | if replace_source: |
| 781 | workspace.delete_tables_by_source_file(safe_name) |
| 782 | |
| 783 | file_type = get_file_type(safe_name) |
| 784 | content = file.stream.read() |
| 785 | content = normalize_text_encoding(content, file_type) |
| 786 | |
| 787 | sheet_hint = request.form.get('sheet_name') or None |
| 788 | df = _read_upload_to_df( |
| 789 | content, file_type, |
| 790 | table_name=sanitized_table_name, |
| 791 | sheet_hint=sheet_hint, |
| 792 | ) |
| 793 | |
| 794 | meta = workspace.write_parquet(df, sanitized_table_name) |
| 795 | meta.source_type = "upload" |
| 796 | meta.source_file = safe_name |
| 797 | meta.original_name = table_name |
| 798 | workspace.add_table_metadata(meta) |
| 799 | |
| 800 | sanitized_table_name = meta.name |
| 801 | row_count = meta.row_count |
| 802 | columns = [c.name for c in (meta.columns or [])] |
| 803 | else: |
| 804 | # raw_data can come as a file upload (Blob) or as a form field |
| 805 | if 'raw_data' in request.files: |
| 806 | raw_bytes = request.files['raw_data'].read() |
| 807 | # Auto-detect gzip (magic bytes 0x1f 0x8b) |
| 808 | if raw_bytes[:2] == b'\x1f\x8b': |
| 809 | raw_data = gzip.decompress(raw_bytes).decode('utf-8') |
| 810 | else: |
| 811 | raw_data = raw_bytes.decode('utf-8') |
| 812 | else: |
nothing calls this directly
no test coverage detected